diff options
author | Ole Loots <ole@monochrom.net> | 2014-09-12 23:22:26 +0200 |
---|---|---|
committer | Ole Loots <ole@monochrom.net> | 2014-09-12 23:22:26 +0200 |
commit | a9ac9c00fc2c73705db242a459160f14d279cdcd (patch) | |
tree | 5f9aa630340bad67934e6fdbfda7f239f0fade57 /gtk | |
parent | 181bc41a9aa200cfac5bf4b84175003639fce488 (diff) | |
parent | 9e6b0fb8b07cd3147b0a2727d3644860cf7c8c7e (diff) | |
download | netsurf-a9ac9c00fc2c73705db242a459160f14d279cdcd.tar.gz netsurf-a9ac9c00fc2c73705db242a459160f14d279cdcd.tar.bz2 |
Merge branch 'master' of git://git.netsurf-browser.org/netsurf
Conflicts:
atari/gui.h
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/Makefile.defaults | 51 | ||||
-rw-r--r-- | gtk/Makefile.target | 40 | ||||
-rw-r--r-- | gtk/bitmap.c | 135 | ||||
-rw-r--r-- | gtk/compat.h | 2 | ||||
-rw-r--r-- | gtk/dialogs/about.c | 85 | ||||
-rw-r--r-- | gtk/dialogs/about.h | 4 | ||||
-rw-r--r-- | gtk/dialogs/preferences.c | 158 | ||||
-rw-r--r-- | gtk/dialogs/source.c | 540 | ||||
-rw-r--r-- | gtk/download.c | 55 | ||||
-rw-r--r-- | gtk/download.h | 2 | ||||
-rw-r--r-- | gtk/fetch.c (renamed from gtk/filetype.c) | 103 | ||||
-rw-r--r-- | gtk/fetch.h (renamed from gtk/filetype.h) | 11 | ||||
-rw-r--r-- | gtk/font_pango.c | 8 | ||||
-rw-r--r-- | gtk/gui.c | 914 | ||||
-rw-r--r-- | gtk/gui.h | 14 | ||||
-rw-r--r-- | gtk/hotlist.c | 6 | ||||
-rw-r--r-- | gtk/login.c | 2 | ||||
-rw-r--r-- | gtk/menu.c | 201 | ||||
-rw-r--r-- | gtk/menu.h | 70 | ||||
-rw-r--r-- | gtk/options.h | 4 | ||||
-rw-r--r-- | gtk/plotters.c | 5 | ||||
l--------- | gtk/res/C/Messages | 1 | ||||
l--------- | gtk/res/C/credits.html | 1 | ||||
l--------- | gtk/res/C/licence.html | 1 | ||||
l--------- | gtk/res/C/welcome.html | 1 | ||||
l--------- | gtk/res/Messages | 1 | ||||
-rw-r--r-- | gtk/res/SearchEngines | 14 | ||||
l--------- | gtk/res/credits.html | 1 | ||||
-rw-r--r-- | gtk/res/gtkdefault.css | 2 | ||||
l--------- | gtk/res/licence.html | 1 | ||||
-rw-r--r-- | gtk/res/options.gtk2.ui | 927 | ||||
-rw-r--r-- | gtk/res/options.gtk3.ui | 81 | ||||
-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 | ||||
l--------- | gtk/res/welcome.html | 1 | ||||
-rw-r--r-- | gtk/scaffolding.c | 1364 | ||||
-rw-r--r-- | gtk/scaffolding.h | 153 | ||||
-rw-r--r-- | gtk/schedule.c | 23 | ||||
-rw-r--r-- | gtk/schedule.h | 3 | ||||
-rw-r--r-- | gtk/search.c | 206 | ||||
-rw-r--r-- | gtk/search.h | 15 | ||||
-rw-r--r-- | gtk/selection.c | 27 | ||||
-rw-r--r-- | gtk/selection.h | 3 | ||||
-rw-r--r-- | gtk/tabs.c | 2 | ||||
-rw-r--r-- | gtk/tabs.h | 2 | ||||
-rw-r--r-- | gtk/theme.c | 32 | ||||
-rw-r--r-- | gtk/theme.h | 2 | ||||
-rw-r--r-- | gtk/toolbar.c | 126 | ||||
-rw-r--r-- | gtk/toolbar.h | 17 | ||||
-rw-r--r-- | gtk/treeview.c | 75 | ||||
-rw-r--r-- | gtk/treeview.h | 12 | ||||
-rw-r--r-- | gtk/viewdata.c | 988 | ||||
-rw-r--r-- | gtk/viewdata.h | 48 | ||||
-rw-r--r-- | gtk/viewsource.c | 76 | ||||
-rw-r--r-- | gtk/viewsource.h (renamed from gtk/dialogs/source.h) | 11 | ||||
-rw-r--r-- | gtk/window.c | 358 | ||||
-rw-r--r-- | gtk/window.h | 8 |
57 files changed, 4265 insertions, 2820 deletions
diff --git a/gtk/Makefile.defaults b/gtk/Makefile.defaults index 23d4c1749..b7382e71b 100644 --- a/gtk/Makefile.defaults +++ b/gtk/Makefile.defaults @@ -2,33 +2,42 @@ # GTK-specific options # ---------------------------------------------------------------------------- - # Where to search for NetSurf's resources after looking in ~/.netsurf and - # $NETSURFRES. It must have a trailing / - NETSURF_GTK_RESOURCES := $(PREFIX)/share/netsurf/ +# Where to search for NetSurf's resources after looking in ~/.netsurf and +# $NETSURFRES. It must have a trailing / +NETSURF_GTK_RESOURCES := $(PREFIX)/share/netsurf/ - # Where to install the netsurf binary - NETSURF_GTK_BIN := $(PREFIX)/bin/ +# Where to install the netsurf binary +NETSURF_GTK_BIN := $(PREFIX)/bin/ - # Enable NetSurf's use of librsvg in conjunction with Cairo to display SVGs - # Valid options: YES, NO, AUTO - NETSURF_USE_RSVG := AUTO +# Enable NetSurf's use of librsvg in conjunction with Cairo to display SVGs +# Valid options: YES, NO, AUTO +NETSURF_USE_RSVG := AUTO - # Enable NetSurf's use of libsvgtiny for displaying SVGs - # Valid options: YES, NO, AUTO - NETSURF_USE_NSSVG := AUTO +# Enable NetSurf's use of libsvgtiny for displaying SVGs +# Valid options: YES, NO, AUTO +NETSURF_USE_NSSVG := AUTO - # Enable NetSurf's use of librosprite for displaying RISC OS Sprites - # Valid options: YES, NO, AUTO - NETSURF_USE_ROSPRITE := AUTO +# Enable NetSurf's use of librosprite for displaying RISC OS Sprites +# Valid options: YES, NO, AUTO +NETSURF_USE_ROSPRITE := AUTO - # Configuration overrides for Mac OS X - ifeq ($(HOST),macosx) +# Enable building the source object cache filesystem based backing store. +NETSURF_FS_BACKING_STORE := YES + +# Configuration overrides for Mac OS X +ifeq ($(HOST),macosx) + NETSURF_USE_LIBICONV_PLUG := NO + NETSURF_USE_HARU_PDF := NO +endif + +# Configuration overrides for OpenBSD +ifeq ($(HOST),OpenBSD) NETSURF_USE_LIBICONV_PLUG := NO NETSURF_USE_HARU_PDF := NO - endif +endif - # Set default GTK version to build for (2 or 3) - NETSURF_GTK_MAJOR := 2 +# Set default GTK version to build for (2 or 3) +NETSURF_GTK_MAJOR := 2 - # Optimisation levels - CFLAGS += -O2 +# Optimisation levels +CFLAGS += -O2 diff --git a/gtk/Makefile.target b/gtk/Makefile.target index ae67fd7f4..05865ff74 100644 --- a/gtk/Makefile.target +++ b/gtk/Makefile.target @@ -44,14 +44,13 @@ GTKDEPFLAGS := -DG_DISABLE_SINGLE_INCLUDES \ # libsexy currently means we cannot enable this # -DGDK_DISABLE_DEPRECATED -GTKCFLAGS := -std=c99 -Dgtk -Dnsgtk \ +GTKCFLAGS := -std=c99 -Dgtk -Dnsgtk -g \ $(GTKDEPFLAGS) \ -D_BSD_SOURCE \ -D_XOPEN_SOURCE=600 \ - -D_POSIX_C_SOURCE=200112L \ + -D_POSIX_C_SOURCE=200809L \ -D_NETBSD_SOURCE \ - -DGTK_RESPATH=\"$(NETSURF_GTK_RESOURCES)\" \ - $(WARNFLAGS) -g + -DGTK_RESPATH=\"$(NETSURF_GTK_RESOURCES)\" # non optional pkg-configed libs $(eval $(call pkg_config_find_and_add,libcss,CSS)) @@ -62,8 +61,6 @@ $(eval $(call pkg_config_find_and_add,libcurl,Curl )) $(eval $(call pkg_config_find_and_add,gtk+-$(NETSURF_GTK_MAJOR).0,GTK-$(NETSURF_GTK_MAJOR))) $(eval $(call pkg_config_find_and_add,gthread-2.0,GThread2)) $(eval $(call pkg_config_find_and_add,gmodule-2.0,GModule2)) -$(eval $(call pkg_config_find_and_add,lcms,lcms)) - CFLAGS += $(GTKCFLAGS) LDFLAGS += -lm @@ -109,10 +106,10 @@ $(eval $(foreach V,$(filter GTK_IMAGE_%,$(.VARIABLES)),$(call convert_image,$($( # S_GTK are sources purely for the GTK build 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 filetype.c download.c menu.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 @@ -127,28 +124,31 @@ EXETARGET := nsgtk # Install target # ---------------------------------------------------------------------------- -GTK_RESOURCES_LIST := adblock.css arrow_down_8x32.png ca-bundle.txt default.css \ - default.ico favicon.png gtkdefault.css internal.css \ - languages license netsurf.png netsurf.xpm \ - netsurf-16x16.xpm quirks.css themelist toolbarIndices \ - SearchEngines -GTK_RESOURCES_LIST := $(addprefix gtk/res/, $(GTK_RESOURCES_LIST)) \ - $(wildcard gtk/res/*.gtk*.ui) +GTK_RESOURCES_LIST := \ + languages themelist SearchEngines toolbarIndices ca-bundle.txt \ + default.css adblock.css quirks.css internal.css gtkdefault.css \ + credits.html licence.html welcome.html Messages \ + default.ico favicon.png netsurf.png netsurf.xpm netsurf-16x16.xpm \ + arrow_down_8x32.png + +GTK_RESOURCES_LIST := \ + $(addprefix gtk/res/, $(GTK_RESOURCES_LIST)) \ + $(wildcard gtk/res/*.gtk$(NETSURF_GTK_MAJOR).ui) # translations with more than just Messages files GTK_TRANSLATIONS_HTML := de en fr it ja nl install-gtk: - $(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)throbber - $(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)icons $(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_BIN) $(Q)install nsgtk $(DESTDIR)$(NETSURF_GTK_BIN)netsurf - $(Q)install -m 0644 $(GTK_RESOURCES_LIST) $(DESTDIR)$(NETSURF_GTK_RESOURCES) + $(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)icons $(Q)install -m 0644 gtk/res/icons/*.png $(DESTDIR)$(NETSURF_GTK_RESOURCES)/icons + $(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)throbber $(Q)install -m 0644 gtk/res/throbber/*.png $(DESTDIR)$(NETSURF_GTK_RESOURCES)/throbber $(Q)tar -c -h -C gtk/res -f - themes | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f - - $(Q)tar -c -h -C gtk/res -f - C $(GTK_TRANSLATIONS_HTML) | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f - + $(Q)tar -c -h -C gtk/res -f - $(GTK_TRANSLATIONS_HTML) | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f - $(call split_install_messages, gtk, $(DESTDIR)$(NETSURF_GTK_RESOURCES)) + $(Q)install -m 0644 $(GTK_RESOURCES_LIST) $(DESTDIR)$(NETSURF_GTK_RESOURCES) # ---------------------------------------------------------------------------- # Package target diff --git a/gtk/bitmap.c b/gtk/bitmap.c index 96e9edaee..3ae211497 100644 --- a/gtk/bitmap.c +++ b/gtk/bitmap.c @@ -187,48 +187,76 @@ unsigned char *bitmap_get_buffer(void *vbitmap) struct bitmap *gbitmap = (struct bitmap *)vbitmap; int pixel_loop; int pixel_count; - uint32_t *pixels; - uint32_t pixel; + uint8_t *pixels; + uint32_t t, r, g, b; cairo_format_t fmt; assert(gbitmap); cairo_surface_flush(gbitmap->surface); - pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface); + pixels = cairo_image_surface_get_data(gbitmap->surface); if (!gbitmap->converted) - return (unsigned char *) pixels; + return pixels; fmt = cairo_image_surface_get_format(gbitmap->surface); pixel_count = cairo_image_surface_get_width(gbitmap->surface) * cairo_image_surface_get_height(gbitmap->surface); if (fmt == CAIRO_FORMAT_RGB24) { + /* Opaque image */ for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) { - pixel = pixels[pixel_loop]; - pixels[pixel_loop] = (pixel & 0xff00ff00) | - ((pixel & 0xff) << 16) | - ((pixel & 0xff0000) >> 16); + /* Cairo surface is ARGB, written in native endian */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + b = pixels[4 * pixel_loop + 0]; + g = pixels[4 * pixel_loop + 1]; + r = pixels[4 * pixel_loop + 2]; + t = pixels[4 * pixel_loop + 3]; +#else + t = pixels[4 * pixel_loop + 0]; + r = pixels[4 * pixel_loop + 1]; + g = pixels[4 * pixel_loop + 2]; + b = pixels[4 * pixel_loop + 3]; +#endif + + /* Core bitmaps always have a component order of rgba, + * regardless of system endianness */ + pixels[4 * pixel_loop + 0] = r; + pixels[4 * pixel_loop + 1] = g; + pixels[4 * pixel_loop + 2] = b; + pixels[4 * pixel_loop + 3] = t; } } else { - uint32_t t, r, g, b; + /* Alpha image: de-multiply alpha */ for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) { - pixel = pixels[pixel_loop]; - t = (pixel & 0xff000000) >> 24; - if (t == 0) { - pixels[pixel_loop] = 0; - } else { - r = ((pixel & 0xff0000) >> 8) / t; - g = ((pixel & 0xff00)) / t; - b = ((pixel & 0xff) << 8) / t; +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + b = pixels[4 * pixel_loop + 0]; + g = pixels[4 * pixel_loop + 1]; + r = pixels[4 * pixel_loop + 2]; + t = pixels[4 * pixel_loop + 3]; +#else + t = pixels[4 * pixel_loop + 0]; + r = pixels[4 * pixel_loop + 1]; + g = pixels[4 * pixel_loop + 2]; + b = pixels[4 * pixel_loop + 3]; +#endif + + if (t != 0) { + r = (r << 8) / t; + g = (g << 8) / t; + b = (b << 8) / t; r = (r > 255) ? 255 : r; g = (g > 255) ? 255 : g; b = (b > 255) ? 255 : b; - - pixels[pixel_loop] = (t << 24) | - (r) | (g << 8) | (b << 16); + } else { + r = g = b = 0; } + + pixels[4 * pixel_loop + 0] = r; + pixels[4 * pixel_loop + 1] = g; + pixels[4 * pixel_loop + 2] = b; + pixels[4 * pixel_loop + 3] = t; } } @@ -319,8 +347,8 @@ void bitmap_modified(void *vbitmap) { struct bitmap *gbitmap = (struct bitmap *)vbitmap; int pixel_loop; int pixel_count; - uint32_t *pixels; - uint32_t pixel; + uint8_t *pixels; + uint32_t t, r, g, b; cairo_format_t fmt; assert(gbitmap); @@ -329,7 +357,7 @@ void bitmap_modified(void *vbitmap) { pixel_count = cairo_image_surface_get_width(gbitmap->surface) * cairo_image_surface_get_height(gbitmap->surface); - pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface); + pixels = cairo_image_surface_get_data(gbitmap->surface); if (gbitmap->converted) { cairo_surface_mark_dirty(gbitmap->surface); @@ -337,30 +365,55 @@ void bitmap_modified(void *vbitmap) { } if (fmt == CAIRO_FORMAT_RGB24) { + /* Opaque image */ for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) { - pixel = pixels[pixel_loop]; - pixels[pixel_loop] = (pixel & 0xff00ff00) | - ((pixel & 0xff) << 16) | - ((pixel & 0xff0000) >> 16); + /* Core bitmaps always have a component order of rgba, + * regardless of system endianness */ + r = pixels[4 * pixel_loop + 0]; + g = pixels[4 * pixel_loop + 1]; + b = pixels[4 * pixel_loop + 2]; + t = pixels[4 * pixel_loop + 3]; + + /* Cairo surface is ARGB, written in native endian */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + pixels[4 * pixel_loop + 0] = b; + pixels[4 * pixel_loop + 1] = g; + pixels[4 * pixel_loop + 2] = r; + pixels[4 * pixel_loop + 3] = t; +#else + pixels[4 * pixel_loop + 0] = t; + pixels[4 * pixel_loop + 1] = r; + pixels[4 * pixel_loop + 2] = g; + pixels[4 * pixel_loop + 3] = b; +#endif } } else { - uint8_t t, r, g, b; + /* Alpha image: pre-multiply alpha */ for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) { - pixel = pixels[pixel_loop]; - t = (pixel & 0xff000000) >> 24; - if (t == 0) { - pixels[pixel_loop] = 0; + r = pixels[4 * pixel_loop + 0]; + g = pixels[4 * pixel_loop + 1]; + b = pixels[4 * pixel_loop + 2]; + t = pixels[4 * pixel_loop + 3]; + + if (t != 0) { + r = ((r * (t + 1)) >> 8) & 0xff; + g = ((g * (t + 1)) >> 8) & 0xff; + b = ((b * (t + 1)) >> 8) & 0xff; } else { - r = (pixel & 0xff0000) >> 16; - g = (pixel & 0xff00) >> 8; - b = pixel & 0xff; - - pixels[pixel_loop] = (t << 24) | - ((r * t) >> 8) | - ((g * t) >> 8) << 8 | - ((b * t) >> 8) << 16; - + r = g = b = 0; } + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + pixels[4 * pixel_loop + 0] = b; + pixels[4 * pixel_loop + 1] = g; + pixels[4 * pixel_loop + 2] = r; + pixels[4 * pixel_loop + 3] = t; +#else + pixels[4 * pixel_loop + 0] = t; + pixels[4 * pixel_loop + 1] = r; + pixels[4 * pixel_loop + 2] = g; + pixels[4 * pixel_loop + 3] = b; +#endif } } diff --git a/gtk/compat.h b/gtk/compat.h index b8c91d914..ee2ebb293 100644 --- a/gtk/compat.h +++ b/gtk/compat.h @@ -23,6 +23,8 @@ #ifndef NETSURF_GTK_COMPAT_H_ #define NETSURF_GTK_COMPAT_H_ +#include <stdint.h> + #include <gtk/gtk.h> void nsgtk_widget_set_can_focus(GtkWidget *widget, gboolean can_focus); diff --git a/gtk/dialogs/about.c b/gtk/dialogs/about.c index 3ebb4c078..a86bfe70f 100644 --- a/gtk/dialogs/about.c +++ b/gtk/dialogs/about.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Mike Lester <element3260@gmail.com> + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -16,63 +16,56 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/** + * \file gtk/dialogs/about.c + * + * Implementation of gtk about dialog. + */ + #include <stdint.h> +#include "utils/utils.h" +#include "utils/messages.h" +#include "utils/nsoption.h" +#include "desktop/browser.h" + #include "gtk/compat.h" #include "gtk/gui.h" #include "gtk/dialogs/about.h" -#include "desktop/browser.h" - +/** + * About dialog information button click. + * + * \param button The button widget that was clicked + * \param data The text of the url to open + */ static void -nsgtk_about_dialog_credits(GtkWidget *button, gpointer data) +nsgtk_about_dialog_info(GtkWidget *button, gpointer data) { - struct browser_window *bw = data; nsurl *url; + nserror ret; + const char *url_text = data; + enum browser_window_create_flags flags = BW_CREATE_HISTORY; - if (nsurl_create("about:credits", &url) != NSERROR_OK) { - warn_user("NoMemory", 0); - } else { - browser_window_navigate(bw, - url, - NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, - NULL, - NULL, - NULL); - nsurl_unref(url); + if (nsoption_bool(show_single_tab) == true) { + flags |= BW_CREATE_TAB; } - gtk_widget_destroy(gtk_widget_get_toplevel(button)); -} - -static void -nsgtk_about_dialog_licence(GtkWidget *button, gpointer data) -{ - struct browser_window *bw = data; - nsurl *url; - - if (nsurl_create("about:licence", &url) != NSERROR_OK) { - warn_user("NoMemory", 0); - } else { - browser_window_navigate(bw, - url, - NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, - NULL, - NULL, - NULL); + ret = nsurl_create(url_text, &url); + if (ret == NSERROR_OK) { + ret = browser_window_create(flags, url, NULL, NULL, NULL); nsurl_unref(url); } + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); + } + + /* close about dialog */ gtk_widget_destroy(gtk_widget_get_toplevel(button)); } -void nsgtk_about_dialog_init(GtkWindow *parent, - struct browser_window *bw, - const char *version) +void nsgtk_about_dialog_init(GtkWindow *parent, const char *version) { GtkWidget *dialog, *vbox, *button, *image, *label; gchar *name_string; @@ -90,7 +83,7 @@ void nsgtk_about_dialog_init(GtkWindow *parent, vbox = nsgtk_vbox_new(FALSE, 8); gtk_box_pack_start(GTK_BOX(nsgtk_dialog_get_content_area(GTK_DIALOG(dialog))), vbox, TRUE, TRUE, 0); - + if (pixbufs != NULL) { GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf(GDK_PIXBUF(g_list_nth_data(pixbufs, 0))); @@ -104,7 +97,7 @@ void nsgtk_about_dialog_init(GtkWindow *parent, gtk_box_pack_start(GTK_BOX (vbox), image, FALSE, FALSE, 0); } - + label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (label), name_string); @@ -113,7 +106,7 @@ void nsgtk_about_dialog_init(GtkWindow *parent, gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - label = gtk_label_new("NetSurf is a small fast web browser"); + label = gtk_label_new("NetSurf is a small fast web browser"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); @@ -136,14 +129,14 @@ void nsgtk_about_dialog_init(GtkWindow *parent, gtk_box_pack_end(GTK_BOX(nsgtk_dialog_get_action_area(GTK_DIALOG(dialog))), button, FALSE, TRUE, 0); gtk_button_box_set_child_secondary (GTK_BUTTON_BOX(nsgtk_dialog_get_action_area(GTK_DIALOG(dialog))), button, TRUE); - g_signal_connect(button, "clicked", G_CALLBACK(nsgtk_about_dialog_credits), (gpointer)bw); + g_signal_connect(button, "clicked", G_CALLBACK(nsgtk_about_dialog_info), (gpointer)"about:credits"); /* Add the Licence button */ button = gtk_button_new_from_stock ("Licence"); - gtk_box_pack_end(GTK_BOX (GTK_DIALOG(nsgtk_dialog_get_action_area(GTK_DIALOG(dialog)))), + gtk_box_pack_end(GTK_BOX (nsgtk_dialog_get_action_area(GTK_DIALOG(dialog))), button, FALSE, TRUE, 0); gtk_button_box_set_child_secondary (GTK_BUTTON_BOX(nsgtk_dialog_get_action_area(GTK_DIALOG(dialog))), button, TRUE); - g_signal_connect(button, "clicked", G_CALLBACK(nsgtk_about_dialog_licence), (gpointer)bw); + g_signal_connect(button, "clicked", G_CALLBACK(nsgtk_about_dialog_info), (gpointer)"about:licence"); /* Ensure that the dialog box is destroyed when the user responds. */ diff --git a/gtk/dialogs/about.h b/gtk/dialogs/about.h index e34a7bff7..1ca0d86b3 100644 --- a/gtk/dialogs/about.h +++ b/gtk/dialogs/about.h @@ -19,8 +19,6 @@ #ifndef NETSURF_GTK_ABOUT_H #define NETSURF_GTK_ABOUT_H -#include "desktop/browser.h" - -void nsgtk_about_dialog_init(GtkWindow *parent, struct browser_window *bw, const char *version); +void nsgtk_about_dialog_init(GtkWindow *parent, const char *version); #endif diff --git a/gtk/dialogs/preferences.c b/gtk/dialogs/preferences.c index 0669f8d9f..f38c7e9bc 100644 --- a/gtk/dialogs/preferences.c +++ b/gtk/dialogs/preferences.c @@ -18,13 +18,15 @@ #include <stdint.h> #include <math.h> +#include <string.h> -#include "desktop/browser_private.h" -#include "utils/nsoption.h" -#include "desktop/searchweb.h" -#include "utils/log.h" #include "utils/utils.h" #include "utils/messages.h" +#include "utils/nsoption.h" +#include "utils/file.h" +#include "utils/log.h" +#include "desktop/browser.h" +#include "desktop/searchweb.h" #include "gtk/compat.h" #include "gtk/window.h" @@ -51,6 +53,7 @@ struct ppref { /* dynamic list stores */ GtkListStore *themes; GtkListStore *content_language; + GtkListStore *search_providers; }; static struct ppref ppref; @@ -105,6 +108,27 @@ nsgtk_preferences_##WIDGET##_realize(GtkWidget *widget, struct ppref *priv) \ ((gdouble)nsoption_int(OPTION)) / MULTIPLIER); \ } +#define SPINBUTTON_UINT_SIGNALS(WIDGET, OPTION, MULTIPLIER) \ +G_MODULE_EXPORT void \ +nsgtk_preferences_##WIDGET##_valuechanged(GtkSpinButton *spinbutton, \ + struct ppref *priv); \ +G_MODULE_EXPORT void \ +nsgtk_preferences_##WIDGET##_valuechanged(GtkSpinButton *spinbutton, \ + struct ppref *priv) \ +{ \ + nsoption_set_uint(OPTION, \ + round(gtk_spin_button_get_value(spinbutton) * MULTIPLIER)); \ +} \ + \ +G_MODULE_EXPORT void \ +nsgtk_preferences_##WIDGET##_realize(GtkWidget *widget, struct ppref *priv); \ +G_MODULE_EXPORT void \ +nsgtk_preferences_##WIDGET##_realize(GtkWidget *widget, struct ppref *priv) \ +{ \ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), \ + ((gdouble)nsoption_uint(OPTION)) / MULTIPLIER); \ +} + #define ENTRY_SIGNALS(WIDGET, OPTION) \ G_MODULE_EXPORT void \ nsgtk_preferences_##WIDGET##_changed(GtkEditable *editable, struct ppref *priv); \ @@ -146,8 +170,8 @@ G_MODULE_EXPORT void nsgtk_preferences_checkShowSingleTab_toggled(GtkToggleButto G_MODULE_EXPORT void nsgtk_preferences_checkShowSingleTab_realize(GtkWidget *widget, struct ppref *priv); G_MODULE_EXPORT void nsgtk_preferences_comboTabPosition_changed(GtkComboBox *widget, struct ppref *priv); G_MODULE_EXPORT void nsgtk_preferences_comboTabPosition_realize(GtkWidget *widget, struct ppref *priv); -G_MODULE_EXPORT void nsgtk_preferences_sourceButtonWindow_toggled(GtkToggleButton *togglebutton, struct ppref *priv); -G_MODULE_EXPORT void nsgtk_preferences_sourceButtonWindow_realize(GtkWidget *widget, struct ppref *priv); +G_MODULE_EXPORT void nsgtk_preferences_comboDeveloperView_changed(GtkComboBox *widget, struct ppref *priv); +G_MODULE_EXPORT void nsgtk_preferences_comboDeveloperView_realize(GtkWidget *widget, struct ppref *priv); G_MODULE_EXPORT void nsgtk_preferences_comboButtonType_changed(GtkComboBox *widget, struct ppref *priv); G_MODULE_EXPORT void nsgtk_preferences_comboButtonType_realize(GtkWidget *widget, struct ppref *priv); G_MODULE_EXPORT void nsgtk_preferences_setCurrentPage_clicked(GtkButton *button, struct ppref *priv); @@ -369,7 +393,7 @@ SPINBUTTON_SIGNALS(spinHistoryAge, history_age, 1.0) SPINBUTTON_SIGNALS(spinMemoryCacheSize, memory_cache_size, (1024*1024)) /* disc cache size */ -SPINBUTTON_SIGNALS(spinDiscCacheSize, disc_cache_size, (1024*1024)) +SPINBUTTON_UINT_SIGNALS(spinDiscCacheSize, disc_cache_size, (1024*1024)) /* disc cache age */ @@ -587,7 +611,7 @@ nsgtk_preferences_comboboxLanguage_realize(GtkWidget *widget, G_MODULE_EXPORT void nsgtk_preferences_comboTheme_changed(GtkComboBox *combo, struct ppref *priv) { - nsgtk_scaffolding *current = scaf_list; + struct nsgtk_scaffolding *current; int theme = 0; gchar *name; GtkTreeIter iter; @@ -619,7 +643,8 @@ nsgtk_preferences_comboTheme_changed(GtkComboBox *combo, struct ppref *priv) g_free(name); } - while (current) { + current = nsgtk_scaffolding_iterate(NULL); + while (current != NULL) { nsgtk_theme_implement(current); current = nsgtk_scaffolding_iterate(current); } @@ -773,12 +798,13 @@ G_MODULE_EXPORT void nsgtk_preferences_comboTabPosition_changed(GtkComboBox *widget, struct ppref *priv) { - nsgtk_scaffolding *current = scaf_list; + struct nsgtk_scaffolding *current; /* set the option */ nsoption_set_int(position_tab, gtk_combo_box_get_active(widget)); /* update all notebooks in all scaffolds */ + current = nsgtk_scaffolding_iterate(NULL); while (current) { nsgtk_scaffolding_reset_offset(current); @@ -796,25 +822,23 @@ nsgtk_preferences_comboTabPosition_realize(GtkWidget *widget, nsoption_int(position_tab)); } -/* Source */ - -/* source view opening */ -TOGGLEBUTTON_SIGNALS(sourceButtonTab, source_tab) +/* Tools */ +/* developer view opening */ G_MODULE_EXPORT void -nsgtk_preferences_sourceButtonWindow_toggled(GtkToggleButton *togglebutton, - struct ppref *priv) +nsgtk_preferences_comboDeveloperView_changed(GtkComboBox *widget, + struct ppref *priv) { - nsoption_set_bool(source_tab, - !gtk_toggle_button_get_active(togglebutton)); + /* set the option */ + nsoption_set_int(developer_view, gtk_combo_box_get_active(widget)); } G_MODULE_EXPORT void -nsgtk_preferences_sourceButtonWindow_realize(GtkWidget *widget, +nsgtk_preferences_comboDeveloperView_realize(GtkWidget *widget, struct ppref *priv) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), - !nsoption_bool(source_tab)); + gtk_combo_box_set_active(GTK_COMBO_BOX(widget), + nsoption_int(developer_view)); } @@ -830,13 +854,15 @@ G_MODULE_EXPORT void nsgtk_preferences_comboButtonType_changed(GtkComboBox *widget, struct ppref *priv) { - nsgtk_scaffolding *current = scaf_list; + struct nsgtk_scaffolding *current; + nsoption_set_int(button_type, gtk_combo_box_get_active(widget) + 1); - /* value of 0 is reserved for 'unset' */ - while (current) { + current = nsgtk_scaffolding_iterate(NULL); + while (current != NULL) { nsgtk_scaffolding_reset_offset(current); switch(nsoption_int(button_type)) { + /* value of 0 is reserved for 'unset' */ case 1: gtk_toolbar_set_style( GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), @@ -893,13 +919,7 @@ ENTRY_SIGNALS(entryHomePageURL, homepage_url) G_MODULE_EXPORT void nsgtk_preferences_setCurrentPage_clicked(GtkButton *button, struct ppref *priv) { - const gchar *url; - - if (priv->bw != NULL) { - url = nsurl_access(hlcache_handle_get_url(priv->bw->current_content)); - } else { - url = "about:blank"; - } + const gchar *url = nsurl_access(browser_window_get_url(priv->bw)); if (priv->entryHomePageURL != NULL) { gtk_entry_set_text(GTK_ENTRY(priv->entryHomePageURL), url); @@ -928,8 +948,6 @@ TOGGLEBUTTON_SIGNALS(checkUrlSearch, search_url_bar) G_MODULE_EXPORT void nsgtk_preferences_comboSearch_changed(GtkComboBox *widget, struct ppref *priv) { - nsgtk_scaffolding *current = scaf_list; - char *name; int provider; provider = gtk_combo_box_get_active(widget); @@ -937,36 +955,29 @@ nsgtk_preferences_comboSearch_changed(GtkComboBox *widget, struct ppref *priv) /* set the option */ nsoption_set_int(search_provider, provider); - /* refresh web search prefs from file */ - search_web_provider_details(provider); - - /* retrieve ico */ - search_web_retrieve_ico(false); - - /* callback may handle changing gui */ - if (search_web_ico() != NULL) { - gui_window_set_search_ico(search_web_ico()); - } - - /* set entry */ - name = search_web_provider_name(); - if (name != NULL) { - char content[strlen(name) + SLEN("Search ") + 1]; - - sprintf(content, "Search %s", name); - free(name); - while (current) { - nsgtk_scaffolding_set_websearch(current, content); - current = nsgtk_scaffolding_iterate(current); - } - } + /* set search provider */ + search_web_select_provider(provider); } G_MODULE_EXPORT void nsgtk_preferences_comboSearch_realize(GtkWidget *widget, struct ppref *priv) { - gtk_combo_box_set_active(GTK_COMBO_BOX(widget), - nsoption_int(search_provider)); + int iter; + const char *name; + int provider = nsoption_int(search_provider); + + if (priv->search_providers != NULL) { + gtk_list_store_clear(priv->search_providers); + for (iter = search_web_iterate_providers(0, &name); + iter != -1; + iter = search_web_iterate_providers(iter, &name)) { + gtk_list_store_insert_with_values(priv->search_providers, + NULL, -1, + 0, name, -1); + } + } + + gtk_combo_box_set_active(GTK_COMBO_BOX(widget), provider); } @@ -1009,8 +1020,14 @@ nsgtk_preferences_fileChooserDownloads_realize(GtkWidget *widget, G_MODULE_EXPORT void nsgtk_preferences_dialogPreferences_response(GtkDialog *dlg, gint resid) { + char *choices = NULL; + if (resid == GTK_RESPONSE_CLOSE) { - nsoption_write(options_file_location, NULL, NULL); + netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); + if (choices != NULL) { + nsoption_write(choices, NULL, NULL); + free(choices); + } gtk_widget_hide(GTK_WIDGET(dlg)); } } @@ -1019,18 +1036,32 @@ G_MODULE_EXPORT gboolean nsgtk_preferences_dialogPreferences_deleteevent(GtkDialog *dlg, struct ppref *priv) { - nsoption_write(options_file_location, NULL, NULL); + char *choices = NULL; + + netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); + if (choices != NULL) { + nsoption_write(choices, NULL, NULL); + free(choices); + } + gtk_widget_hide(GTK_WIDGET(dlg)); - /* delt with it by hiding window, no need to destory widget by - * default */ + /* Delt with it by hiding window, no need to destory widget by + * default. + */ return TRUE; } G_MODULE_EXPORT void nsgtk_preferences_dialogPreferences_destroy(GtkDialog *dlg, struct ppref *priv) { - nsoption_write(options_file_location, NULL, NULL); + char *choices = NULL; + + netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); + if (choices != NULL) { + nsoption_write(choices, NULL, NULL); + free(choices); + } } @@ -1076,6 +1107,7 @@ GtkWidget* nsgtk_preferences(struct browser_window *bw, GtkWindow *parent) priv->entryHomePageURL = GB(ENTRY, entryHomePageURL); priv->themes = GB(LIST_STORE, liststore_themes); priv->content_language = GB(LIST_STORE, liststore_content_language); + priv->search_providers = GB(LIST_STORE, liststore_search_provider); priv->entryProxyHost = GB(ENTRY, entryProxyHost); priv->spinProxyPort = GB(SPIN_BUTTON, spinProxyPort); priv->entryProxyUser = GB(ENTRY, entryProxyUser); diff --git a/gtk/dialogs/source.c b/gtk/dialogs/source.c deleted file mode 100644 index 5306bdc16..000000000 --- a/gtk/dialogs/source.c +++ /dev/null @@ -1,540 +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 <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <gtk/gtk.h> - -#include "gtk/compat.h" -#include "gtk/dialogs/source.h" -#include "gtk/dialogs/about.h" -#include "gtk/window.h" -#include "gtk/gui.h" -#include "gtk/print.h" -#include "gtk/selection.h" -#include "desktop/browser_private.h" -#include "desktop/netsurf.h" -#include "desktop/print.h" -#include "utils/nsoption.h" -#include "utils/messages.h" -#include "utils/url.h" -#include "utils/utils.h" -#include "utils/utf8.h" -#include "render/html.h" -#include "render/font.h" -#include "content/content.h" -#include "content/content_type.h" - -#include "utils/log.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; - -void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw); - -#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); - -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; -} - -void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw) -{ - char glade_Location[strlen(res_dir_location) + SLEN("source.gtk2.ui") - + 1]; - if (content_get_type(bw->current_content) != CONTENT_HTML) - return; - - if (nsoption_bool(source_tab)) { - nsgtk_source_tab_init(parent, bw); - return; - } - - sprintf(glade_Location, "%ssource.gtk2.ui", res_dir_location); - - GError* error = NULL; - 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; - } - - - const char *source_data; - unsigned long source_size; - char *data = NULL; - size_t data_len; - - source_data = content_get_source_data(bw->current_content, - &source_size); - - utf8_convert_ret r = utf8_from_enc( - source_data, - html_get_encoding(bw->current_content), - source_size, - &data, - &data_len); - if (r == UTF8_CONVERT_NOMEM) { - warn_user("NoMemory",0); - return; - } else if (r == UTF8_CONVERT_BADENC) { - warn_user("EncNotRec",0); - return; - } - - GtkWindow *wndSource = GTK_WINDOW(gtk_builder_get_object( - glade_File, "wndSource")); - GtkWidget *cutbutton = GTK_WIDGET(gtk_builder_get_object( - glade_File, "source_cut")); - GtkWidget *pastebutton = GTK_WIDGET(gtk_builder_get_object( - glade_File, "source_paste")); - GtkWidget *deletebutton = GTK_WIDGET(gtk_builder_get_object( - glade_File, "source_delete")); - GtkWidget *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); - - struct nsgtk_source_window *thiswindow = - malloc(sizeof(struct nsgtk_source_window)); - if (thiswindow == NULL) { - free(data); - warn_user("NoMemory", 0); - return; - } - - thiswindow->url = strdup(nsurl_access(hlcache_handle_get_url( - bw->current_content))); - if (thiswindow->url == NULL) { - free(thiswindow); - free(data); - warn_user("NoMemory", 0); - return; - } - - 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); - - GtkTextView *sourceview = GTK_TEXT_VIEW( - gtk_builder_get_object(glade_File, - "source_view")); - - PangoFontDescription *fontdesc = - pango_font_description_from_string("Monospace 8"); - - thiswindow->gv = sourceview; - nsgtk_widget_modify_font(GTK_WIDGET(sourceview), fontdesc); - - GtkTextBuffer *tb = gtk_text_view_get_buffer(sourceview); - gtk_text_buffer_set_text(tb, thiswindow->data, -1); - - gtk_widget_show(GTK_WIDGET(wndSource)); - -} - -/** - * create a new tab with page source - */ -void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw) -{ - const char *source_data; - unsigned long source_size; - char *ndata = 0; - size_t ndata_len; - nsurl *url; - nserror error; - utf8_convert_ret r; - gchar *filename; - char *fileurl; - gint handle; - - source_data = content_get_source_data(bw->current_content, - &source_size); - - r = utf8_from_enc(source_data, - html_get_encoding(bw->current_content), - source_size, - &ndata, - &ndata_len); - if (r == UTF8_CONVERT_NOMEM) { - warn_user("NoMemory",0); - return; - } else if (r == UTF8_CONVERT_BADENC) { - warn_user("EncNotRec",0); - return; - } - - handle = g_file_open_tmp("nsgtksourceXXXXXX", &filename, NULL); - if ((handle == -1) || (filename == NULL)) { - warn_user(messages_get("gtkSourceTabError"), 0); - free(ndata); - return; - } - close (handle); /* in case it was binary mode */ - - FILE *f = fopen(filename, "w"); - if (f == NULL) { - warn_user(messages_get("gtkSourceTabError"), 0); - g_free(filename); - free(ndata); - return; - } - - fprintf(f, "%s", ndata); - fclose(f); - free(ndata); - fileurl = path_to_url(filename); - g_free(filename); - if (fileurl == NULL) { - warn_user(messages_get("NoMemory"), 0); - return; - } - - /* Open tab */ - error = nsurl_create(fileurl, &url); - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } else { - error = browser_window_create(BROWSER_WINDOW_VERIFIABLE | - BROWSER_WINDOW_TAB, - url, - NULL, - bw, - NULL); - nsurl_unref(url); - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } - } - free(fileurl); -} - -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; - url_func_result res; - - res = url_nice(nsg->url, &filename, false); - if (res != URL_FUNC_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, nsg->bw, netsurf_version); - - return TRUE; -} diff --git a/gtk/download.c b/gtk/download.c index e882ec798..3a321ec5f 100644 --- a/gtk/download.c +++ b/gtk/download.c @@ -25,12 +25,14 @@ #include "utils/log.h" #include "utils/utils.h" -#include "utils/url.h" +#include "utils/nsurl.h" #include "utils/messages.h" +#include "utils/nsoption.h" +#include "desktop/download.h" #include "desktop/gui.h" + #include "gtk/gui.h" #include "gtk/scaffolding.h" -#include "utils/nsoption.h" #include "gtk/download.h" #include "gtk/window.h" #include "gtk/compat.h" @@ -712,10 +714,10 @@ static void nsgtk_download_store_create_item (struct gui_download_window *dl) NSGTK_DOWNLOAD, dl, -1); } -struct gui_download_window *gui_download_window_create(download_context *ctx, - struct gui_window *gui) +static struct gui_download_window * +gui_download_window_create(download_context *ctx, struct gui_window *gui) { - const char *url = download_context_get_url(ctx); + nsurl *url = download_context_get_url(ctx); unsigned long total_size = download_context_get_total_length(ctx); gchar *domain; gchar *destination; @@ -728,17 +730,22 @@ struct gui_download_window *gui_download_window_create(download_context *ctx, nsgtk_scaffolding_window(nsgtk_get_scaffold(gui)); struct gui_download_window *download = malloc(sizeof *download); - if (download == NULL) + if (download == NULL) { return NULL; + } - if (url_host(url, &domain) != URL_FUNC_OK) { + /* set the domain to the host component of the url if it exists */ + if (nsurl_has_component(url, NSURL_HOST)) { + domain = g_strdup(lwc_string_data(nsurl_get_component(url, NSURL_HOST))); + } else { domain = g_strdup(messages_get("gtkUnknownHost")); - if (domain == NULL) { - free(download); - return NULL; - } + } + if (domain == NULL) { + free(download); + return NULL; } + /* show the dialog */ destination = nsgtk_download_dialog_show( download_context_get_filename(ctx), domain, size); if (destination == NULL) { @@ -797,7 +804,7 @@ struct gui_download_window *gui_download_window_create(download_context *ctx, } -nserror gui_download_window_data(struct gui_download_window *dw, +static nserror gui_download_window_data(struct gui_download_window *dw, const char *data, unsigned int size) { g_io_channel_write_chars(dw->write, data, size, NULL, &dw->error); @@ -820,13 +827,13 @@ nserror gui_download_window_data(struct gui_download_window *dw, } -void gui_download_window_error(struct gui_download_window *dw, +static void gui_download_window_error(struct gui_download_window *dw, const char *error_msg) { } -void gui_download_window_done(struct gui_download_window *dw) +static void gui_download_window_done(struct gui_download_window *dw) { g_io_channel_shutdown(dw->write, TRUE, &dw->error); g_io_channel_unref(dw->write); @@ -845,17 +852,11 @@ void gui_download_window_done(struct gui_download_window *dw) } +static struct gui_download_table download_table = { + .create = gui_download_window_create, + .data = gui_download_window_data, + .error = gui_download_window_error, + .done = gui_download_window_done, +}; - - - - - - - - - - - - - +struct gui_download_table *nsgtk_download_table = &download_table; diff --git a/gtk/download.h b/gtk/download.h index e85c4126a..a6e624fbd 100644 --- a/gtk/download.h +++ b/gtk/download.h @@ -21,6 +21,8 @@ #include <gtk/gtk.h> +struct gui_download_table *nsgtk_download_table; + bool nsgtk_download_init(const char *glade_file_location); void nsgtk_download_destroy (void); bool nsgtk_check_for_downloads(GtkWindow *parent); diff --git a/gtk/filetype.c b/gtk/fetch.c index 2ae59d867..42ba89839 100644 --- a/gtk/filetype.c +++ b/gtk/fetch.c @@ -1,6 +1,5 @@ /* - * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org> - * Copyright 2007 Vincent Sanders <vince@debian.org> + * Copyright 2014 vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -18,18 +17,21 @@ */ #include <stdio.h> -#include <stdbool.h> -#include <string.h> #include <stdlib.h> -#include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <ctype.h> +#include <string.h> -#include "gtk/filetype.h" -#include "content/fetch.h" -#include "utils/log.h" #include "utils/hashtable.h" +#include "utils/log.h" +#include "utils/filepath.h" +#include "utils/file.h" +#include "desktop/gui.h" + +#include "gtk/gui.h" +#include "gtk/fetch.h" static struct hash_table *mime_hash = NULL; @@ -43,9 +45,8 @@ void gtk_fetch_filetype_init(const char *mimefile) /* first, check to see if /etc/mime.types in preference */ if ((stat("/etc/mime.types", &statbuf) == 0) && - S_ISREG(statbuf.st_mode)) { + S_ISREG(statbuf.st_mode)) { mimefile = "/etc/mime.types"; - } fh = fopen(mimefile, "r"); @@ -75,25 +76,30 @@ void gtk_fetch_filetype_init(const char *mimefile) while (!feof(fh)) { char line[256], *ptr, *type, *ext; + if (fgets(line, 256, fh) == NULL) - break; + break; + if (!feof(fh) && line[0] != '#') { ptr = line; /* search for the first non-whitespace character */ - while (isspace(*ptr)) + while (isspace(*ptr)) { ptr++; + } /* is this line empty other than leading whitespace? */ - if (*ptr == '\n' || *ptr == '\0') + if (*ptr == '\n' || *ptr == '\0') { continue; + } type = ptr; /* search for the first non-whitespace char or NUL or * NL */ - while (*ptr && (!isspace(*ptr)) && *ptr != '\n') + while (*ptr && (!isspace(*ptr)) && *ptr != '\n') { ptr++; + } if (*ptr == '\0' || *ptr == '\n') { /* this mimetype has no extensions - read next @@ -106,8 +112,9 @@ void gtk_fetch_filetype_init(const char *mimefile) /* search for the first non-whitespace character which * will be the first filename extenion */ - while (isspace(*ptr)) + while (isspace(*ptr)) { ptr++; + } while(true) { ext = ptr; @@ -115,9 +122,11 @@ void gtk_fetch_filetype_init(const char *mimefile) /* search for the first whitespace char or * NUL or NL which is the end of the ext. */ - while (*ptr && (!isspace(*ptr)) && - *ptr != '\n') + while (*ptr && + (!isspace(*ptr)) && + *ptr != '\n') { ptr++; + } if (*ptr == '\0' || *ptr == '\n') { /* special case for last extension on @@ -134,8 +143,11 @@ void gtk_fetch_filetype_init(const char *mimefile) /* search for the first non-whitespace char or * NUL or NL, to find start of next ext. */ - while (*ptr && (isspace(*ptr)) && *ptr != '\n') + while (*ptr && + (isspace(*ptr)) && + *ptr != '\n') { ptr++; + } } } } @@ -162,8 +174,9 @@ const char *fetch_filetype(const char *unix_path) return "text/plain"; } - if (S_ISDIR(statbuf.st_mode)) + if (S_ISDIR(statbuf.st_mode)) { return "application/x-netsurf-directory"; + } l = strlen(unix_path); @@ -184,11 +197,13 @@ const char *fetch_filetype(const char *unix_path) } ptr = unix_path + strlen(unix_path); - while (*ptr != '.' && *ptr != '/') + while (*ptr != '.' && *ptr != '/') { ptr--; + } - if (*ptr != '.') + if (*ptr != '.') { return "text/plain"; + } ext = strdup(ptr + 1); /* skip the . */ @@ -196,7 +211,7 @@ const char *fetch_filetype(const char *unix_path) * copy is lower case too. */ lowerchar = ext; - while(*lowerchar) { + while (*lowerchar) { *lowerchar = tolower(*lowerchar); lowerchar++; } @@ -204,36 +219,38 @@ const char *fetch_filetype(const char *unix_path) type = hash_get(mime_hash, ext); free(ext); - return type != NULL ? type : "text/plain"; -} + if (type == NULL) { + type = "text/plain"; + } -char *fetch_mimetype(const char *unix_path) -{ - return strdup(fetch_filetype(unix_path)); + return type; } -#ifdef TEST_RIG -int main(int argc, char *argv[]) +static nsurl *gui_get_resource_url(const char *path) { - unsigned int c1, *c2; - const char *key; - - gtk_fetch_filetype_init("./mime.types"); + char buf[PATH_MAX]; + nsurl *url = NULL; - c1 = 0; c2 = 0; - - while ( (key = hash_iterate(mime_hash, &c1, &c2)) != NULL) { - printf("%s ", key); + /* default.css -> gtkdefault.css */ + if (strcmp(path, "default.css") == 0) { + path = "gtkdefault.css"; } - printf("\n"); - - if (argc > 1) { - printf("%s maps to %s\n", argv[1], fetch_filetype(argv[1])); + /* favicon.ico -> favicon.png */ + if (strcmp(path, "favicon.ico") == 0) { + path = "favicon.png"; } - gtk_fetch_filetype_fin(); + netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url); + + return url; } -#endif +static struct gui_fetch_table fetch_table = { + .filetype = fetch_filetype, + + .get_resource_url = gui_get_resource_url, +}; + +struct gui_fetch_table *nsgtk_fetch_table = &fetch_table; diff --git a/gtk/filetype.h b/gtk/fetch.h index 8bf98db7c..a095adbf9 100644 --- a/gtk/filetype.h +++ b/gtk/fetch.h @@ -1,6 +1,5 @@ /* - * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org> - * Copyright 2007 Vincent Sanders <vince@debian.org> + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -17,5 +16,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef NETSURF_GTK_FETCH_H +#define NETSURF_GTK_FETCH_H + +struct gui_fetch_table *nsgtk_fetch_table; + void gtk_fetch_filetype_init(const char *mimefile); void gtk_fetch_filetype_fin(void); +const char *fetch_filetype(const char *unix_path); + +#endif diff --git a/gtk/font_pango.c b/gtk/font_pango.c index 6c7f1592f..1cb536e9e 100644 --- a/gtk/font_pango.c +++ b/gtk/font_pango.c @@ -27,8 +27,6 @@ #include <stdio.h> #include <gtk/gtk.h> -#include "css/css.h" -#include "css/utils.h" #include "gtk/font_pango.h" #include "gtk/plotters.h" #include "render/font.h" @@ -235,17 +233,11 @@ bool nsfont_paint(int x, int y, const char *string, size_t length, PangoFontDescription *desc; PangoLayout *layout; PangoLayoutLine *line; - gint size; if (length == 0) return true; desc = nsfont_style_to_description(fstyle); - size = (gint)(pango_font_description_get_size(desc)); - if (pango_font_description_get_size_is_absolute(desc)) - pango_font_description_set_absolute_size(desc, size); - else - pango_font_description_set_size(desc, size); layout = pango_cairo_create_layout(current_cr); @@ -33,18 +33,19 @@ #include <sys/select.h> #include <sys/stat.h> #include <sys/types.h> -#include <curl/curl.h> #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include <glib.h> #include "content/content.h" #include "content/fetch.h" +#include "content/fetchers.h" #include "content/fetchers/curl.h" #include "content/fetchers/resource.h" #include "content/hlcache.h" #include "content/urldb.h" -#include "desktop/browser_private.h" +#include "content/backing_store.h" +#include "desktop/browser.h" #include "desktop/gui.h" #include "desktop/netsurf.h" #include "utils/nsoption.h" @@ -55,11 +56,19 @@ #include "desktop/textinput.h" #include "desktop/tree.h" #include "css/utils.h" +#include "render/form.h" +#include "utils/filepath.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "utils/file.h" + #include "gtk/compat.h" #include "gtk/completion.h" #include "gtk/cookies.h" #include "gtk/download.h" -#include "gtk/filetype.h" +#include "gtk/fetch.h" #include "gtk/gui.h" #include "gtk/history.h" #include "gtk/hotlist.h" @@ -67,22 +76,17 @@ #include "gtk/treeview.h" #include "gtk/window.h" #include "gtk/schedule.h" +#include "gtk/selection.h" +#include "gtk/search.h" -#include "render/form.h" -#include "utils/filepath.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/url.h" -#include "utils/utf8.h" -#include "utils/utils.h" -char *options_file_location; char *toolbar_indices_file_location; char *res_dir_location; -char *print_options_file_location; char *languages_file_location; char *themelist_file_location; +char *nsgtk_config_home; /* exported global defined in gtk/gui.h */ + GdkPixbuf *favicon_pixbuf; /* favicon default pixbuf */ struct glade_file_location_s *glade_file_location; @@ -107,7 +111,7 @@ static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data); #define THROBBER_FRAMES 9 -static char **respaths; /** resource search path vector */ +char **respaths; /** resource search path vector */ /** Create an array of valid paths to search for resources. * @@ -183,7 +187,7 @@ nsgtk_new_ui(char **respath, const char *name, GtkBuilder **pglade) filepath = filepath_find(respath, resname); if (filepath == NULL) { - snprintf(errorstr, NEW_GLADE_ERROR_SIZE, + snprintf(errorstr, NEW_GLADE_ERROR_SIZE, "Unable to locate %s glade template file.\n", name); die(errorstr); } @@ -192,7 +196,7 @@ nsgtk_new_ui(char **respath, const char *name, GtkBuilder **pglade) if (!gtk_builder_add_from_file(builder, filepath, &error)) { g_warning ("Couldn't load builder file: %s", error->message); g_error_free (error); - snprintf(errorstr, NEW_GLADE_ERROR_SIZE, + snprintf(errorstr, NEW_GLADE_ERROR_SIZE, "Unable to load glade %s window definitions.\n", name); die(errorstr); @@ -204,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; @@ -212,7 +221,7 @@ nsgtk_new_ui(char **respath, const char *name, GtkBuilder **pglade) /** * Load definitions from glade files. */ -static void +static void nsgtk_init_glade(char **respath) { GtkBuilder *gladeWarning; @@ -233,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")); @@ -240,48 +250,59 @@ nsgtk_init_glade(char **respath) } /** - * Set option defaults for gtk frontend + * Set option defaults for gtk frontend. * * @param defaults The option table to update. * @return error status. */ static nserror set_defaults(struct nsoption_s *defaults) { - char *hdir = getenv("HOME"); - char buf[PATH_MAX]; + char *fname; - /* Set defaults for absent option strings */ - snprintf(buf, PATH_MAX, "%s/.netsurf/Cookies", hdir); - nsoption_setnull_charp(cookie_file, strdup(buf)); - nsoption_setnull_charp(cookie_jar, strdup(buf)); - if (nsoption_charp(cookie_file) == NULL || - nsoption_charp(cookie_jar) == NULL) { - LOG(("Failed initialising cookie options")); - return NSERROR_BAD_PARAMETER; + /* cookie file default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies"); + if (fname != NULL) { + nsoption_setnull_charp(cookie_file, fname); } - if (nsoption_charp(downloads_directory) == NULL) { - snprintf(buf, PATH_MAX, "%s/", hdir); - nsoption_set_charp(downloads_directory, strdup(buf)); + /* cookie jar default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies"); + if (fname != NULL) { + nsoption_setnull_charp(cookie_jar, fname); } - if (nsoption_charp(url_file) == NULL) { - snprintf(buf, PATH_MAX, "%s/.netsurf/URLs", hdir); - nsoption_set_charp(url_file, strdup(buf)); + /* url database default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs"); + if (fname != NULL) { + nsoption_setnull_charp(url_file, fname); } - if (nsoption_charp(hotlist_path) == NULL) { - snprintf(buf, PATH_MAX, "%s/.netsurf/Hotlist", hdir); - nsoption_set_charp(hotlist_path, strdup(buf)); + /* bookmark database default */ + fname = NULL; + netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist"); + if (fname != NULL) { + nsoption_setnull_charp(hotlist_path, fname); } + /* download directory default */ + fname = getenv("HOME"); + if (fname != NULL) { + nsoption_setnull_charp(downloads_directory, strdup(fname)); + } + + /* default path to certificates */ nsoption_setnull_charp(ca_path, strdup("/etc/ssl/certs")); - if (nsoption_charp(url_file) == NULL || - nsoption_charp(ca_path) == NULL || - nsoption_charp(downloads_directory) == NULL || - nsoption_charp(hotlist_path) == NULL) { - LOG(("Failed initialising string options")); + if ((nsoption_charp(cookie_file) == NULL) || + (nsoption_charp(cookie_jar) == NULL) || + (nsoption_charp(url_file) == NULL) || + (nsoption_charp(hotlist_path) == NULL) || + (nsoption_charp(downloads_directory) == NULL) || + (nsoption_charp(ca_path) == NULL)) { + LOG(("Failed initialising default resource paths")); return NSERROR_BAD_PARAMETER; } @@ -295,55 +316,7 @@ static nserror set_defaults(struct nsoption_s *defaults) return NSERROR_OK; } -static void check_options(char **respath) -{ - char *hdir = getenv("HOME"); - char buf[PATH_MAX]; - nsoption_set_bool(core_select_menu, true); - - /* Attempt to handle nonsense status bar widths. These may exist - * in people's Choices as the GTK front end used to abuse the - * status bar width option by using it for an absolute value in px. - * The GTK front end now correctly uses it as a proportion of window - * width. Here we assume that a value of less than 15% is wrong - * and set to the default two thirds. */ - if (nsoption_int(toolbar_status_size) < 1500) { - nsoption_set_int(toolbar_status_size, 6667); - } - - /* user options should be stored in the users home directory */ - snprintf(buf, PATH_MAX, "%s/.netsurf/Choices", hdir); - options_file_location = strdup(buf); - - filepath_sfinddef(respath, buf, "Print", "~/.netsurf/"); - LOG(("Using '%s' as Print Settings file", buf)); - print_options_file_location = strdup(buf); - - -} - -nsurl *gui_get_resource_url(const char *path) -{ - char buf[PATH_MAX]; - char *raw; - nsurl *url = NULL; - /* default.css -> gtkdefault.css */ - if (strcmp(path, "default.css") == 0) - path = "gtkdefault.css"; - - /* favicon.ico -> favicon.png */ - if (strcmp(path, "favicon.ico") == 0) - path = "favicon.png"; - - raw = path_to_url(filepath_sfind(respaths, buf, path)); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } - - return url; -} /** @@ -357,32 +330,32 @@ static void gui_init(int argc, char** argv, char **respath) nsurl *url; nserror error; - /* find the languages file */ + /* find the languages file */ languages_file_location = filepath_find(respath, "languages"); - if ((languages_file_location == NULL) || + if ((languages_file_location == NULL) || (strlen(languages_file_location) < 10)) { - die("Unable to find resources.\n"); + die("Unable to find resources.\n"); } - /* find the theme list file */ + /* find the theme list file */ themelist_file_location = filepath_find(respath, "themelist"); if ((themelist_file_location != NULL) && (strlen(themelist_file_location) < 10)) { free(themelist_file_location); themelist_file_location = NULL; } - if (themelist_file_location == NULL) { + if (themelist_file_location == NULL) { LOG(("Unable to find themelist - disabling")); } - /* Obtain resources path location. + /* Obtain resources path location. * * Uses the directory the languages file was found in, * @todo find and slaughter all references to this! */ res_dir_location = calloc(1, strlen(languages_file_location) - 8); - memcpy(res_dir_location, - languages_file_location, + memcpy(res_dir_location, + languages_file_location, strlen(languages_file_location) - 9); LOG(("Using '%s' for resource path", res_dir_location)); @@ -397,12 +370,12 @@ static void gui_init(int argc, char** argv, char **respath) } /* Search engine sources */ - search_engines_file_location = filepath_find(respath, "SearchEngines"); - LOG(("Using '%s' as Search Engines file", search_engines_file_location)); - - /* Default Icon */ - search_default_ico_location = filepath_find(respath, "default.ico"); - LOG(("Using '%s' as default search ico", search_default_ico_location)); + resource_filename = filepath_find(respath, "SearchEngines"); + search_web_init(resource_filename); + if (resource_filename != NULL) { + LOG(("Using '%s' as Search Engines file", resource_filename)); + free(resource_filename); + } /* Default favicon */ resource_filename = filepath_find(respath, "favicon.png"); @@ -411,7 +384,7 @@ static void gui_init(int argc, char** argv, char **respath) free(resource_filename); if (favicon_pixbuf == NULL) { favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, 16,16); - + } } @@ -419,7 +392,7 @@ static void gui_init(int argc, char** argv, char **respath) toolbar_indices_file_location = filepath_find(respath, "toolbarIndices"); LOG(("Using '%s' as custom toolbar settings file", toolbar_indices_file_location)); - /* load throbber images */ + /* load throbber images */ if (nsgtk_throbber_init(respath, THROBBER_FRAMES) == false) die("Unable to load throbber image.\n"); @@ -459,13 +432,15 @@ static void gui_init(int argc, char** argv, char **respath) if (argc > 1) { struct stat fs; if (stat(argv[1], &fs) == 0) { + size_t addrlen; char *rp = realpath(argv[1], NULL); assert(rp != NULL); - addr = malloc(SLEN("file://") + strlen(rp) + /*\0 */ 1); + + /* calculate file url length including terminator */ + addrlen = SLEN("file://") + strlen(rp) + 1; + addr = malloc(addrlen); assert(addr != NULL); - /* These are safe thanks to the above sum */ - strcpy(addr, "file://"); - strcat(addr, rp); + snprintf(addr, addrlen, "file://%s", rp); free(rp); } else { addr = strdup(argv[1]); @@ -482,8 +457,7 @@ static void gui_init(int argc, char** argv, char **respath) /* create an initial browser window */ error = nsurl_create(addr, &url); if (error == NSERROR_OK) { - error = browser_window_create(BROWSER_WINDOW_VERIFIABLE | - BROWSER_WINDOW_HISTORY, + error = browser_window_create(BW_CREATE_HISTORY, url, NULL, NULL, @@ -501,157 +475,55 @@ static void gui_init(int argc, char** argv, char **respath) } -/** - * Check that ~/.netsurf/ exists, and if it doesn't, create it. - */ -static void nsgtk_check_homedir(void) -{ - char *hdir = getenv("HOME"); - char buf[PATH_MAX]; - - if (hdir == NULL) { - /* we really can't continue without a home directory. */ - LOG(("HOME is not set - nowhere to store state!")); - die("NetSurf requires HOME to be set in order to run.\n"); - - } - - snprintf(buf, PATH_MAX, "%s/.netsurf", hdir); - if (access(buf, F_OK) != 0) { - LOG(("You don't have a ~/.netsurf - creating one for you.")); - if (mkdir(buf, S_IRWXU) == -1) { - LOG(("Unable to create %s", buf)); - die("NetSurf requires ~/.netsurf to exist, but it cannot be created.\n"); - } - } else { - if (chmod(buf, S_IRWXU) != 0) { - LOG(("Unable to set permissions on %s", buf)); - } - } -} /** * Ensures output logging stream is correctly configured */ static bool nslog_stream_configure(FILE *fptr) { - /* set log stream to be non-buffering */ + /* set log stream to be non-buffering */ setbuf(fptr, NULL); return true; } -/** - * Main entry point from OS. - */ -int main(int argc, char** argv) -{ - char *messages; - char *options; - nserror ret; - - /* check home directory is available */ - nsgtk_check_homedir(); - - respaths = nsgtk_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"GTK_RESPATH":./gtk/res"); - - gtk_init(&argc, &argv); - - /* initialise logging. Not fatal if it fails but not much we - * can do about it either. - */ - nslog_init(nslog_stream_configure, &argc, argv); - - /* user options setup */ - ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); - if (ret != NSERROR_OK) { - fprintf(stderr, "Options failed to initialise (%s)\n", - messages_get_errorcode(ret)); - return 1; - } - options = filepath_find(respaths, "Choices"); - nsoption_read(options, nsoptions); - free(options); - nsoption_commandline(&argc, argv, nsoptions); - check_options(respaths); /* check user options */ - - /* common initialisation */ - messages = filepath_find(respaths, "Messages"); - ret = netsurf_init(messages); - free(messages); - if (ret != NSERROR_OK) { - fprintf(stderr, "NetSurf core failed to initialise (%s)\n", - messages_get_errorcode(ret)); - return 1; - } - - /* run the browser */ - gui_init(argc, argv, respaths); - /* Ensure all scaffoldings are destroyed before we go into exit */ - while (scaf_list != NULL) { - nsgtk_scaffolding_destroy(scaf_list); - } - - /* common finalisation */ - netsurf_exit(); - /* finalise options */ - nsoption_finalise(nsoptions, nsoptions_default); - - return 0; -} - - -void gui_poll(bool active) +static void nsgtk_poll(bool active) { - CURLMcode code; fd_set read_fd_set, write_fd_set, exc_fd_set; int max_fd; GPollFD *fd_list[1000]; unsigned int fd_count = 0; bool block = true; - schedule_run(); - - if (browser_reformat_pending) - block = false; - - if (active) { - FD_ZERO(&read_fd_set); - FD_ZERO(&write_fd_set); - FD_ZERO(&exc_fd_set); - code = curl_multi_fdset(fetch_curl_multi, - &read_fd_set, - &write_fd_set, - &exc_fd_set, - &max_fd); - assert(code == CURLM_OK); - for (int i = 0; i <= max_fd; i++) { - if (FD_ISSET(i, &read_fd_set)) { - GPollFD *fd = malloc(sizeof *fd); - fd->fd = i; - fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR; - g_main_context_add_poll(0, fd, 0); - fd_list[fd_count++] = fd; - } - if (FD_ISSET(i, &write_fd_set)) { - GPollFD *fd = malloc(sizeof *fd); - fd->fd = i; - fd->events = G_IO_OUT | G_IO_ERR; - g_main_context_add_poll(0, fd, 0); - fd_list[fd_count++] = fd; - } - if (FD_ISSET(i, &exc_fd_set)) { - GPollFD *fd = malloc(sizeof *fd); - fd->fd = i; - fd->events = G_IO_ERR; - g_main_context_add_poll(0, fd, 0); - fd_list[fd_count++] = fd; - } + fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd); + for (int i = 0; i <= max_fd; i++) { + if (FD_ISSET(i, &read_fd_set)) { + GPollFD *fd = malloc(sizeof *fd); + fd->fd = i; + fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR; + g_main_context_add_poll(0, fd, 0); + fd_list[fd_count++] = fd; + } + if (FD_ISSET(i, &write_fd_set)) { + GPollFD *fd = malloc(sizeof *fd); + fd->fd = i; + fd->events = G_IO_OUT | G_IO_ERR; + g_main_context_add_poll(0, fd, 0); + fd_list[fd_count++] = fd; + } + if (FD_ISSET(i, &exc_fd_set)) { + GPollFD *fd = malloc(sizeof *fd); + fd->fd = i; + fd->events = G_IO_ERR; + g_main_context_add_poll(0, fd, 0); + fd_list[fd_count++] = fd; } } + schedule_run(); + gtk_main_iteration_do(block); for (unsigned int i = 0; i != fd_count; i++) { @@ -659,40 +531,36 @@ void gui_poll(bool active) free(fd_list[i]); } - schedule_run(); - - if (browser_reformat_pending) - nsgtk_window_process_reformats(); } -void gui_quit(void) +static void gui_quit(void) { + LOG(("Quitting GUI")); + + /* Ensure all scaffoldings are destroyed before we go into exit */ nsgtk_download_destroy(); urldb_save_cookies(nsoption_charp(cookie_jar)); urldb_save(nsoption_charp(url_file)); nsgtk_cookies_destroy(); nsgtk_history_destroy(); nsgtk_hotlist_destroy(); - free(print_options_file_location); - free(search_engines_file_location); - free(search_default_ico_location); - free(toolbar_indices_file_location); - gtk_fetch_filetype_fin(); -} - + free(toolbar_indices_file_location); + free(nsgtk_config_home); + gtk_fetch_filetype_fin(); +} static void nsgtk_select_menu_clicked(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { - form_select_process_selection(select_menu_bw->current_content, - select_menu_control, (intptr_t)user_data); + form_select_process_selection(select_menu_control, + (intptr_t)user_data); } -void gui_create_form_select_menu(struct browser_window *bw, +static void gui_create_form_select_menu(struct browser_window *bw, struct form_control *control) { @@ -733,24 +601,21 @@ void gui_create_form_select_menu(struct browser_window *bw, } -void gui_window_save_link(struct gui_window *g, const char *url, - const char *title) -{ -} - -void gui_launch_url(const char *url) +static nserror gui_launch_url(struct nsurl *url) { gboolean ok; GError *error = NULL; - ok = nsgtk_show_uri(NULL, url, GDK_CURRENT_TIME, &error); - if (ok == TRUE) - return; + ok = nsgtk_show_uri(NULL, nsurl_access(url), GDK_CURRENT_TIME, &error); + if (ok == TRUE) { + return NSERROR_OK; + } if (error) { warn_user(messages_get("URIOpenError"), error->message); g_error_free(error); } + return NSERROR_NO_FETCH_HANDLER; } void warn_user(const char *warning, const char *detail) @@ -776,11 +641,11 @@ void die(const char * const error) } -void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, +static void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw) -{ - static struct nsgtk_treeview *ssl_window; +{ + static struct nsgtk_treeview *ssl_window; struct sslcert_session_data *data; GtkButton *accept, *reject; void **session; @@ -788,12 +653,20 @@ void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, GtkScrolledWindow *scrolled; GtkDrawingArea *drawing_area; GError* error = NULL; - GtkBuilder* builder; + GtkBuilder* builder; + + /* state while window is open */ + session = calloc(sizeof(void *), 3); + if (session == NULL) { + return; + } builder = gtk_builder_new (); if (!gtk_builder_add_from_file(builder, glade_file_location->ssl, &error)) { g_warning("Couldn't load builder file: %s", error->message); g_error_free(error); + + free(session); return; } @@ -804,36 +677,31 @@ void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, scrolled = GTK_SCROLLED_WINDOW(gtk_builder_get_object(builder, "SSLScrolled")); drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "SSLDrawingArea")); - session = calloc(sizeof(void *), 3); - - if (session == NULL) { - return; - } ssl_window = nsgtk_treeview_create(TREE_SSLCERT, window, scrolled, drawing_area); - + if (ssl_window == NULL) { free(session); return; } - + accept = GTK_BUTTON(gtk_builder_get_object(builder, "sslaccept")); - reject = GTK_BUTTON(gtk_builder_get_object(builder, "sslreject")); + reject = GTK_BUTTON(gtk_builder_get_object(builder, "sslreject")); session[0] = builder; session[1] = ssl_window; session[2] = data; - + #define CONNECT(obj, sig, callback, ptr) \ - g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) - + g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + CONNECT(accept, "clicked", nsgtk_ssl_accept, session); CONNECT(reject, "clicked", nsgtk_ssl_reject, session); CONNECT(window, "delete_event", G_CALLBACK(nsgtk_ssl_delete_event), (gpointer)session); - - gtk_widget_show(GTK_WIDGET(window)); + + gtk_widget_show(GTK_WIDGET(window)); } void nsgtk_ssl_accept(GtkButton *w, gpointer data) @@ -844,7 +712,7 @@ void nsgtk_ssl_accept(GtkButton *w, gpointer data) struct sslcert_session_data *ssl_data = session[2]; sslcert_viewer_accept(ssl_data); - + nsgtk_treeview_destroy(wnd); g_object_unref(G_OBJECT(x)); free(session); @@ -858,7 +726,7 @@ void nsgtk_ssl_reject(GtkWidget *w, gpointer data) struct sslcert_session_data *ssl_data = session[2]; sslcert_viewer_reject(ssl_data); - + nsgtk_treeview_destroy(wnd); g_object_unref(G_OBJECT(x)); free(session); @@ -870,84 +738,6 @@ gboolean nsgtk_ssl_delete_event(GtkWidget *w, GdkEvent *event, gpointer data) return FALSE; } -utf8_convert_ret utf8_to_local_encoding(const char *string, size_t len, - char **result) -{ - assert(string && result); - - if (len == 0) - len = strlen(string); - - *result = strndup(string, len); - if (!(*result)) - return UTF8_CONVERT_NOMEM; - - return UTF8_CONVERT_OK; -} - - -utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len, - char **result) -{ - assert(string && result); - - if (len == 0) - len = strlen(string); - - *result = strndup(string, len); - if (!(*result)) - return UTF8_CONVERT_NOMEM; - - return UTF8_CONVERT_OK; -} - - -char *path_to_url(const char *path) -{ - int urllen; - char *url; - - if (path == NULL) { - return NULL; - } - - urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1; - - url = malloc(urllen); - if (url == NULL) { - return NULL; - } - - if (*path == '/') { - path++; /* file: paths are already absolute */ - } - - snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path); - - return url; -} - - -char *url_to_path(const char *url) -{ - char *path; - char *respath; - url_func_result res; /* result from url routines */ - - res = url_path(url, &path); - if (res != URL_FUNC_OK) { - return NULL; - } - - res = url_unescape(path, &respath); - free(path); - if (res != URL_FUNC_OK) { - return NULL; - } - - return respath; -} - #ifdef WITH_PDF_EXPORT void PDF_Password(char **owner_pass, char **user_pass, char *path) @@ -1061,7 +851,7 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key) * now. I hope. */ switch (key->keyval) { - + case GDK_KEY(Tab): return KEY_TAB; @@ -1141,49 +931,403 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key) case GDK_KEY(Super_L): case GDK_KEY(Super_R): case GDK_KEY(Hyper_L): - case GDK_KEY(Hyper_R): + case GDK_KEY(Hyper_R): return 0; - default: + default: return gdk_keyval_to_unicode(key->keyval); - } + } +} + + +/** + * create directory name and check it is acessible and a directory. + */ +static nserror +check_dirname(const char *path, const char *leaf, char **dirname_out) +{ + nserror ret; + char *dirname = NULL; + struct stat dirname_stat; + + ret = netsurf_mkpath(&dirname, NULL, 2, path, leaf); + if (ret != NSERROR_OK) { + return ret; + } + + /* ensure access is possible and the entry is actualy + * a directory. + */ + if (stat(dirname, &dirname_stat) == 0) { + if (S_ISDIR(dirname_stat.st_mode)) { + if (access(dirname, R_OK | W_OK) == 0) { + *dirname_out = dirname; + return NSERROR_OK; + } else { + ret = NSERROR_PERMISSION; + } + } else { + ret = NSERROR_NOT_DIRECTORY; + } + } else { + ret = NSERROR_NOT_FOUND; + } + + free(dirname); + + return ret; } /** - * Return the filename part of a full path + * Get the path to the config directory. * - * \param path full path and filename - * \return filename (will be freed with free()) + * @param config_home_out Path to configuration directory. + * @return NSERROR_OK on sucess and \a config_home_out updated else error code. */ +static nserror get_config_home(char **config_home_out) +{ + nserror ret; + char *home_dir; + char *xdg_config_dir; + char *config_home; + + home_dir = getenv("HOME"); + + /* The old $HOME/.netsurf/ directory should be used if it + * exists and is accessible. + */ + if (home_dir != NULL) { + ret = check_dirname(home_dir, ".netsurf", &config_home); + if (ret == NSERROR_OK) { + LOG(("\"%s\"", config_home)); + *config_home_out = config_home; + return ret; + } + } + + /* $XDG_CONFIG_HOME defines the base directory + * relative to which user specific configuration files + * should be stored. + */ + xdg_config_dir = getenv("XDG_CONFIG_HOME"); + + if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) { + /* If $XDG_CONFIG_HOME is either not set or empty, a + * default equal to $HOME/.config should be used. + */ + + /** @todo the meaning of empty is never defined so I + * am assuming it is a zero length string but is it + * supposed to mean "whitespace" and if so what counts + * as whitespace? (are tabs etc. counted or should + * isspace() be used) + */ + + /* the HOME envvar is required */ + if (home_dir == NULL) { + return NSERROR_NOT_DIRECTORY; + } + + ret = check_dirname(home_dir, ".config/netsurf", &config_home); + if (ret != NSERROR_OK) { + return ret; + } + } else { + ret = check_dirname(xdg_config_dir, "netsurf", &config_home); + if (ret != NSERROR_OK) { + return ret; + } + } + + LOG(("\"%s\"", config_home)); + + *config_home_out = config_home; + return NSERROR_OK; +} -char *filename_from_path(char *path) +static nserror create_config_home(char **config_home_out) { - char *leafname; + char *config_home = NULL; + char *home_dir; + char *xdg_config_dir; + nserror ret; + + LOG(("Attempting to create configuration directory")); + + /* $XDG_CONFIG_HOME defines the base directory + * relative to which user specific configuration files + * should be stored. + */ + xdg_config_dir = getenv("XDG_CONFIG_HOME"); + + if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) { + home_dir = getenv("HOME"); - leafname = strrchr(path, '/'); - if (!leafname) - leafname = path; - else - leafname += 1; + if ((home_dir == NULL) || (*home_dir == 0)) { + return NSERROR_NOT_DIRECTORY; + } + + ret = netsurf_mkpath(&config_home, NULL, 4, home_dir, ".config","netsurf", "/"); + if (ret != NSERROR_OK) { + return ret; + } + } else { + ret = netsurf_mkpath(&config_home, NULL, 3, xdg_config_dir, "netsurf", "/"); + if (ret != NSERROR_OK) { + return ret; + } + } - return strdup(leafname); + /* ensure all elements of path exist (the trailing / is required) */ + ret = netsurf_mkdir_all(config_home); + if (ret != NSERROR_OK) { + free(config_home); + return ret; + } + + /* strip the trailing separator */ + config_home[strlen(config_home) - 1] = 0; + + LOG(("\"%s\"", config_home)); + + *config_home_out = config_home; + + return NSERROR_OK; } /** - * Add a path component/filename to an existing path + * Get the path to the cache directory. * - * \param path buffer containing path + free space - * \param length length of buffer "path" - * \param newpart string containing path component to add to path - * \return true on success + * @param cache_home_out Path to cache directory. + * @return NSERROR_OK on sucess and \a cache_home_out updated else error code. */ +static nserror get_cache_home(char **cache_home_out) +{ + nserror ret; + char *xdg_cache_dir; + char *cache_home; + char *home_dir; + + /* $XDG_CACHE_HOME defines the base directory relative to + * which user specific non-essential data files should be + * stored. + */ + xdg_cache_dir = getenv("XDG_CACHE_HOME"); -bool path_add_part(char *path, int length, const char *newpart) + if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) { + /* If $XDG_CACHE_HOME is either not set or empty, a + * default equal to $HOME/.cache should be used. + */ + + home_dir = getenv("HOME"); + + /* the HOME envvar is required */ + if (home_dir == NULL) { + return NSERROR_NOT_DIRECTORY; + } + + ret = check_dirname(home_dir, ".cache/netsurf", &cache_home); + if (ret != NSERROR_OK) { + return ret; + } + } else { + ret = check_dirname(xdg_cache_dir, "netsurf", &cache_home); + if (ret != NSERROR_OK) { + return ret; + } + } + + LOG(("\"%s\"", cache_home)); + + *cache_home_out = cache_home; + return NSERROR_OK; +} + +static nserror create_cache_home(char **cache_home_out) { - if(path[strlen(path) - 1] != '/') - strncat(path, "/", length); + char *cache_home = NULL; + char *home_dir; + char *xdg_cache_dir; + nserror ret; - strncat(path, newpart, length); + LOG(("Attempting to create configuration directory")); - return true; + /* $XDG_CACHE_HOME defines the base directory + * relative to which user specific cache files + * should be stored. + */ + xdg_cache_dir = getenv("XDG_CACHE_HOME"); + + if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) { + home_dir = getenv("HOME"); + + if ((home_dir == NULL) || (*home_dir == 0)) { + return NSERROR_NOT_DIRECTORY; + } + + ret = netsurf_mkpath(&cache_home, NULL, 4, home_dir, ".cache", "netsurf", "/"); + if (ret != NSERROR_OK) { + return ret; + } + } else { + ret = netsurf_mkpath(&cache_home, NULL, 3, xdg_cache_dir, "netsurf", "/"); + if (ret != NSERROR_OK) { + return ret; + } + } + + /* ensure all elements of path exist (the trailing / is required) */ + ret = netsurf_mkdir_all(cache_home); + if (ret != NSERROR_OK) { + free(cache_home); + return ret; + } + + /* strip the trailing separator */ + cache_home[strlen(cache_home) - 1] = 0; + + LOG(("\"%s\"", cache_home)); + + *cache_home_out = cache_home; + + return NSERROR_OK; +} + +static nserror nsgtk_option_init(int *pargc, char** argv) +{ + nserror ret; + char *choices = NULL; + + /* user options setup */ + ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + if (ret != NSERROR_OK) { + return ret; + } + + /* Attempt to load the user choices */ + ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); + if (ret == NSERROR_OK) { + nsoption_read(choices, nsoptions); + free(choices); + } + + /* overide loaded options with those from commandline */ + nsoption_commandline(pargc, argv, nsoptions); + + /* ensure all options fall within sensible bounds */ + + /* select menus generated by core code */ + nsoption_set_bool(core_select_menu, true); + + /* Attempt to handle nonsense status bar widths. These may exist + * in people's Choices as the GTK front end used to abuse the + * status bar width option by using it for an absolute value in px. + * The GTK front end now correctly uses it as a proportion of window + * width. Here we assume that a value of less than 15% is wrong + * and set to the default two thirds. */ + if (nsoption_int(toolbar_status_size) < 1500) { + nsoption_set_int(toolbar_status_size, 6667); + } + + return NSERROR_OK; +} + +static struct gui_browser_table nsgtk_browser_table = { + .poll = nsgtk_poll, + .schedule = nsgtk_schedule, + + .quit = gui_quit, + .launch_url = gui_launch_url, + .create_form_select_menu = gui_create_form_select_menu, + .cert_verify = gui_cert_verify, + .login = gui_401login_open, +}; + +/** + * Main entry point from OS. + */ +int main(int argc, char** argv) +{ + char *messages; + char *cache_home = NULL; + nserror ret; + struct netsurf_table nsgtk_table = { + .browser = &nsgtk_browser_table, + .window = nsgtk_window_table, + .clipboard = nsgtk_clipboard_table, + .download = nsgtk_download_table, + .fetch = nsgtk_fetch_table, + .llcache = filesystem_llcache_table, + .search = nsgtk_search_table, + .search_web = nsgtk_search_web_table, + }; + + ret = netsurf_register(&nsgtk_table); + if (ret != NSERROR_OK) { + die("NetSurf operation table failed registration"); + } + + /* build the common resource path list */ + respaths = nsgtk_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"GTK_RESPATH":./gtk/res"); + + /* Locate the correct user configuration directory path */ + ret = get_config_home(&nsgtk_config_home); + if (ret == NSERROR_NOT_FOUND) { + /* no config directory exists yet so try to create one */ + ret = create_config_home(&nsgtk_config_home); + } + if (ret != NSERROR_OK) { + LOG(("Unable to locate a configuration directory.")); + nsgtk_config_home = NULL; + } + + /* Initialise gtk */ + gtk_init(&argc, &argv); + + /* initialise logging. Not fatal if it fails but not much we + * can do about it either. + */ + nslog_init(nslog_stream_configure, &argc, argv); + + /* Initialise user options */ + ret = nsgtk_option_init(&argc, argv); + if (ret != NSERROR_OK) { + fprintf(stderr, "Options failed to initialise (%s)\n", + messages_get_errorcode(ret)); + return 1; + } + + /* Obtain path to messages */ + messages = filepath_find(respaths, "Messages"); + + /* Locate the correct user cache directory path */ + ret = get_cache_home(&cache_home); + if (ret == NSERROR_NOT_FOUND) { + /* no cache directory exists yet so try to create one */ + ret = create_cache_home(&cache_home); + } + if (ret != NSERROR_OK) { + LOG(("Unable to locate a cache directory.")); + } + + /* core initialisation */ + ret = netsurf_init(messages, cache_home); + free(messages); + free(cache_home); + if (ret != NSERROR_OK) { + fprintf(stderr, "NetSurf core failed to initialise (%s)\n", + messages_get_errorcode(ret)); + return 1; + } + + /* run the browser */ + gui_init(argc, argv, respaths); + + /* common finalisation */ + netsurf_exit(); + + /* finalise options */ + nsoption_finalise(nsoptions, nsoptions_default); + + return 0; } @@ -29,7 +29,8 @@ #include <inttypes.h> #include <stdbool.h> #include <gtk/gtk.h> -//#include <glade/glade.h> + +#include "utils/nsurl.h" struct glade_file_location_s { char *netsurf; @@ -44,6 +45,7 @@ struct glade_file_location_s { char *history; char *hotlist; char *cookies; + char *viewdata; }; /** location of all glade files. */ @@ -51,14 +53,20 @@ extern struct glade_file_location_s *glade_file_location; extern char *languages_file_location; extern char *toolbar_indices_file_location; -extern char *options_file_location; /**< location where user options are written */ extern char *res_dir_location; -extern char *print_options_file_location; extern char *themelist_file_location; +/** Directory where all configuration files are held. */ +extern char *nsgtk_config_home; + extern GdkPixbuf *favicon_pixbuf; /* favicon default pixbuf */ +extern char **respaths; /** resource search path vector */ + uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *); +extern void gui_401login_open(nsurl *url, const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw); + #endif /* GTK_GUI_H */ diff --git a/gtk/hotlist.c b/gtk/hotlist.c index db090992c..0c98bd90c 100644 --- a/gtk/hotlist.c +++ b/gtk/hotlist.c @@ -16,17 +16,19 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <stdlib.h> -#include "desktop/hotlist.h" +#include "utils/log.h" #include "utils/nsoption.h" +#include "desktop/hotlist.h" #include "desktop/plotters.h" #include "desktop/tree.h" + #include "gtk/gui.h" #include "gtk/hotlist.h" #include "gtk/plotters.h" #include "gtk/scaffolding.h" #include "gtk/treeview.h" -#include "utils/log.h" #define GLADE_NAME "hotlist.glade" diff --git a/gtk/login.c b/gtk/login.c index 3b8d68254..f98a78703 100644 --- a/gtk/login.c +++ b/gtk/login.c @@ -28,10 +28,8 @@ #include "content/hlcache.h" #include "content/urldb.h" #include "desktop/browser.h" -#include "desktop/401login.h" #include "desktop/gui.h" #include "utils/messages.h" -#include "utils/url.h" #include "utils/utils.h" struct session_401 { diff --git a/gtk/menu.c b/gtk/menu.c index 7c55a9fd6..065ee6bdf 100644 --- a/gtk/menu.c +++ b/gtk/menu.c @@ -53,6 +53,13 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu, return true; } +#define NEW_MENU(n, m) \ + n = malloc(sizeof(*n)); \ + if (n == NULL) { \ + return NULL; \ + } \ + n->m##_menu = GTK_MENU(gtk_menu_new()) + #define IMAGE_ITEM(p, q, r, s, t)\ nsgtk_menu_add_image_item(s->p##_menu, &(s->q##_menuitem), #r,\ #r "Accel", t) @@ -66,7 +73,7 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu, GTK_WIDGET(s->q##_menuitem));\ gtk_widget_show(GTK_WIDGET(s->q##_menuitem));\ } - + #define SET_SUBMENU(q, r) \ do { \ r->q##_submenu = nsgtk_menu_##q##_submenu(group); \ @@ -76,7 +83,7 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu, gtk_menu_item_set_submenu(GTK_MENU_ITEM(r->q##_menuitem), \ GTK_WIDGET(r->q##_submenu->q##_menu)); \ } \ - } while(0) + } while(0) #define ADD_NAMED_SEP(q, r, s) \ do { \ @@ -85,7 +92,7 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu, gtk_menu_shell_append(GTK_MENU_SHELL(s->q##_menu), s->r##_separator); \ gtk_widget_show(s->r##_separator); \ } \ - } while(0) + } while(0) #define ADD_SEP(q, r) \ do { \ @@ -94,22 +101,20 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu, gtk_menu_shell_append(GTK_MENU_SHELL(r->q##_menu), w); \ gtk_widget_show(w); \ } \ - } while(0) + } while(0) #define ATTACH_PARENT(parent, msgname, menuv, group) \ do { \ - if (parent != NULL) { \ - /* create top level menu entry and attach to parent */ \ - menuv = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(messages_get(#msgname))); \ - gtk_menu_shell_append(parent, GTK_WIDGET(menuv)); \ - gtk_widget_show(GTK_WIDGET(menuv)); \ - /* attach submenu to parent */ \ - gtk_menu_item_set_submenu(menuv, GTK_WIDGET(menuv##_menu)); \ - gtk_menu_set_accel_group(menuv##_menu, group); \ - } \ - } while(0) + /* create top level menu entry and attach to parent */ \ + menuv = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(messages_get(#msgname))); \ + gtk_menu_shell_append(parent, GTK_WIDGET(menuv)); \ + gtk_widget_show(GTK_WIDGET(menuv)); \ + /* attach submenu to parent */ \ + gtk_menu_item_set_submenu(menuv, GTK_WIDGET(menuv##_menu)); \ + gtk_menu_set_accel_group(menuv##_menu, group); \ + } while(0) -/** +/** * creates an export submenu * \param group the 'global' in a gtk sense accelerator reference */ @@ -135,7 +140,7 @@ static struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *gro return ret; } -/** +/** * creates a scaleview submenu * \param group the 'global' in a gtk sense accelerator reference */ @@ -143,7 +148,7 @@ static struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *gro static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu( GtkAccelGroup *group) { - struct nsgtk_scaleview_submenu *ret = + struct nsgtk_scaleview_submenu *ret = malloc(sizeof(struct nsgtk_scaleview_submenu)); if (ret == NULL) { warn_user(messages_get("NoMemory"), 0); @@ -161,7 +166,7 @@ static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu( return ret; } -/** +/** * creates a tab navigation submenu * \param group the 'global' in a gtk sense accelerator reference */ @@ -186,7 +191,7 @@ static struct nsgtk_tabs_submenu *nsgtk_menu_tabs_submenu(GtkAccelGroup *group) return ret; } -/** +/** * creates an images submenu * \param group the 'global' in a gtk sense accelerator reference */ @@ -210,7 +215,7 @@ static struct nsgtk_images_submenu *nsgtk_menu_images_submenu(GtkAccelGroup *gro return ret; } -/** +/** * creates a toolbars submenu * \param group the 'global' in a gtk sense accelerator reference */ @@ -234,38 +239,41 @@ static struct nsgtk_toolbars_submenu *nsgtk_menu_toolbars_submenu( if (ret->menubar_menuitem != NULL) gtk_check_menu_item_set_active(ret->menubar_menuitem, TRUE); CHECK_ITEM(toolbars, toolbar, gtkToolBar, ret) - if (ret->toolbar_menuitem != NULL) + if (ret->toolbar_menuitem != NULL) gtk_check_menu_item_set_active(ret->toolbar_menuitem, TRUE); return ret; } -/** +/** * creates a debugging submenu * \param group the 'global' in a gtk sense accelerator reference */ -static struct nsgtk_debugging_submenu *nsgtk_menu_debugging_submenu( +static struct nsgtk_developer_submenu *nsgtk_menu_developer_submenu( GtkAccelGroup *group) { - struct nsgtk_debugging_submenu *ret = - malloc(sizeof(struct nsgtk_debugging_submenu)); - if (ret == NULL) { + struct nsgtk_developer_submenu *dmenu = + malloc(sizeof(struct nsgtk_developer_submenu)); + if (dmenu == NULL) { warn_user(messages_get("NoMemory"), 0); return NULL; } - ret->debugging_menu = GTK_MENU(gtk_menu_new()); - if (ret->debugging_menu == NULL) { + dmenu->developer_menu = GTK_MENU(gtk_menu_new()); + if (dmenu->developer_menu == NULL) { warn_user(messages_get("NoMemory"), 0); - free(ret); + free(dmenu); return NULL; } - IMAGE_ITEM(debugging, toggledebugging, gtkToggleDebugging, ret, group); - IMAGE_ITEM(debugging, saveboxtree, gtkSaveBoxTree, ret, group); - IMAGE_ITEM(debugging, savedomtree, gtkSaveDomTree, ret, group); - return ret; + + IMAGE_ITEM(developer, viewsource, gtkPageSource, dmenu, group); + IMAGE_ITEM(developer, toggledebugging, gtkToggleDebugging, dmenu, group); + IMAGE_ITEM(developer, debugboxtree, gtkDebugBoxTree, dmenu, group); + IMAGE_ITEM(developer, debugdomtree, gtkDebugDomTree, dmenu, group); + + return dmenu; } - -/** + +/** * creates the file menu * \param group The gtk 'global' accelerator reference * \param parent The parent menu to attach to or NULL @@ -304,7 +312,7 @@ static struct nsgtk_file_menu *nsgtk_menu_file_submenu(GtkAccelGroup *group) return fmenu; } -/** +/** * creates an edit menu * \param group the 'global' in a gtk sense accelerator reference */ @@ -336,7 +344,7 @@ static struct nsgtk_edit_menu *nsgtk_menu_edit_submenu(GtkAccelGroup *group) return ret; } -/** +/** * creates a view menu * \param group the 'global' in a gtk sense accelerator reference */ @@ -359,26 +367,22 @@ static struct nsgtk_view_menu *nsgtk_menu_view_submenu(GtkAccelGroup *group) ADD_SEP(view, ret); IMAGE_ITEM(view, scaleview, gtkScaleView, ret, group); IMAGE_ITEM(view, fullscreen, gtkFullScreen, ret, group); - IMAGE_ITEM(view, viewsource, gtkViewSource, ret, group); ADD_SEP(view, ret); IMAGE_ITEM(view, images, gtkImages, ret, group); IMAGE_ITEM(view, toolbars, gtkToolbars, ret, group); IMAGE_ITEM(view, tabs, gtkTabs, ret, group); ADD_SEP(view, ret); - IMAGE_ITEM(view, downloads, gtkDownloads, ret, group); IMAGE_ITEM(view, savewindowsize, gtkSaveWindowSize, ret, group); - IMAGE_ITEM(view, debugging, gtkDebugging, ret, group); SET_SUBMENU(scaleview, ret); SET_SUBMENU(images, ret); SET_SUBMENU(toolbars, ret); SET_SUBMENU(tabs, ret); - SET_SUBMENU(debugging, ret); return ret; } -/** +/** * creates a nav menu * \param group the 'global' in a gtk sense accelerator reference */ @@ -407,19 +411,42 @@ static struct nsgtk_nav_menu *nsgtk_menu_nav_submenu(GtkAccelGroup *group) IMAGE_ITEM(nav, addbookmarks, gtkAddBookMarks, ret, group); IMAGE_ITEM(nav, showbookmarks, gtkShowBookMarks, ret, group); ADD_SEP(nav, ret); - IMAGE_ITEM(nav, showcookies, gtkShowCookies, ret, group); - ADD_SEP(nav, ret); IMAGE_ITEM(nav, openlocation, gtkOpenLocation, ret, group); return ret; } -/** -* creates a help menu -* \param group the 'global' in a gtk sense accelerator reference -*/ +/** + * creates the tools menu + * \param group the 'global' in a gtk sense accelerator reference + */ +static struct nsgtk_tools_menu *nsgtk_menu_tools_submenu(GtkAccelGroup *group) +{ + struct nsgtk_tools_menu *ret = malloc(sizeof(struct nsgtk_tools_menu)); + if (ret == NULL) { + warn_user(messages_get("NoMemory"), 0); + return NULL; + } + ret->tools_menu = GTK_MENU(gtk_menu_new()); + if (ret->tools_menu == NULL) { + warn_user(messages_get("NoMemory"), 0); + free(ret); + return NULL; + } + + IMAGE_ITEM(tools, downloads, gtkDownloads, ret, group); + IMAGE_ITEM(tools, showcookies, gtkShowCookies, ret, group); + IMAGE_ITEM(tools, developer, gtkDeveloper, ret, group); + SET_SUBMENU(developer, ret); + return ret; +} + +/** + * creates a help menu + * \param group the 'global' in a gtk sense accelerator reference + */ static struct nsgtk_help_menu *nsgtk_menu_help_submenu(GtkAccelGroup *group) { struct nsgtk_help_menu *ret = malloc(sizeof(struct nsgtk_help_menu)); @@ -448,53 +475,46 @@ static struct nsgtk_help_menu *nsgtk_menu_help_submenu(GtkAccelGroup *group) * * Generate the main menu structure and attach it to a menubar widget. */ -struct nsgtk_bar_submenu *nsgtk_menu_bar_create(GtkMenuShell *menubar, GtkAccelGroup *group) +struct nsgtk_bar_submenu * +nsgtk_menu_bar_create(GtkMenuShell *menubar, GtkAccelGroup *group) { - ; struct nsgtk_bar_submenu *nmenu; - nmenu = malloc(sizeof(struct nsgtk_bar_submenu)); + nmenu = calloc(1, sizeof(struct nsgtk_bar_submenu)); if (nmenu == NULL) { - warn_user(messages_get("NoMemory"), 0); return NULL; } - nmenu->bar_menu = GTK_MENU_BAR(menubar); - + /* create sub menus */ nmenu->file_submenu = nsgtk_menu_file_submenu(group); - ATTACH_PARENT(menubar, gtkFile, nmenu->file_submenu->file, group); - nmenu->edit_submenu = nsgtk_menu_edit_submenu(group); - ATTACH_PARENT(menubar, gtkEdit, nmenu->edit_submenu->edit, group); - nmenu->view_submenu = nsgtk_menu_view_submenu(group); - ATTACH_PARENT(menubar, gtkView, nmenu->view_submenu->view, group); - nmenu->nav_submenu = nsgtk_menu_nav_submenu(group); - ATTACH_PARENT(menubar, gtkNavigate, nmenu->nav_submenu->nav, group); - + nmenu->tools_submenu = nsgtk_menu_tools_submenu(group); nmenu->help_submenu = nsgtk_menu_help_submenu(group); - ATTACH_PARENT(menubar, gtkHelp, nmenu->help_submenu->help, group); + + if (menubar != NULL) { + nmenu->bar_menu = GTK_MENU_BAR(menubar); + + /* attach menus to menubar */ + ATTACH_PARENT(menubar, gtkFile, nmenu->file_submenu->file, group); + ATTACH_PARENT(menubar, gtkEdit, nmenu->edit_submenu->edit, group); + ATTACH_PARENT(menubar, gtkView, nmenu->view_submenu->view, group); + ATTACH_PARENT(menubar, gtkNavigate, nmenu->nav_submenu->nav, group); + ATTACH_PARENT(menubar, gtkTools, nmenu->tools_submenu->tools, group); + ATTACH_PARENT(menubar, gtkHelp, nmenu->help_submenu->help, group); + } return nmenu; } -/** - * Generate right click menu menu. - * - */ -struct nsgtk_popup_submenu *nsgtk_menu_popup_create(GtkAccelGroup *group) +/* exported function documented in gtk/menu.h */ +struct nsgtk_popup_menu *nsgtk_popup_menu_create(GtkAccelGroup *group) { - struct nsgtk_popup_submenu *nmenu; + struct nsgtk_popup_menu *nmenu; - nmenu = malloc(sizeof(struct nsgtk_popup_submenu)); - if (nmenu == NULL) { - warn_user(messages_get("NoMemory"), 0); - return NULL; - } + NEW_MENU(nmenu, popup); - nmenu->popup_menu = GTK_MENU(gtk_menu_new()); - IMAGE_ITEM(popup, file, gtkFile, nmenu, group); SET_SUBMENU(file, nmenu); @@ -507,17 +527,14 @@ struct nsgtk_popup_submenu *nsgtk_menu_popup_create(GtkAccelGroup *group) IMAGE_ITEM(popup, nav, gtkNavigate, nmenu, group); SET_SUBMENU(nav, nmenu); + IMAGE_ITEM(popup, tools, gtkTools, nmenu, group); + SET_SUBMENU(tools, nmenu); + IMAGE_ITEM(popup, help, gtkHelp, nmenu, group); SET_SUBMENU(help, nmenu); ADD_NAMED_SEP(popup, first, nmenu); - IMAGE_ITEM(popup, opentab, gtkOpentab, nmenu, group); - IMAGE_ITEM(popup, openwin, gtkOpenwin, nmenu, group); - IMAGE_ITEM(popup, savelink, gtkSavelink, nmenu, group); - - ADD_NAMED_SEP(popup, second, nmenu); - IMAGE_ITEM(popup, back, gtkBack, nmenu, group); IMAGE_ITEM(popup, forward, gtkForward, nmenu, group); @@ -530,6 +547,26 @@ struct nsgtk_popup_submenu *nsgtk_menu_popup_create(GtkAccelGroup *group) IMAGE_ITEM(popup, paste, gtkPaste, nmenu, group); IMAGE_ITEM(popup, customize, gtkCustomize, nmenu, group); + return nmenu; +} + + +/* exported function documented in gtk/menu.h */ +struct nsgtk_link_menu * +nsgtk_link_menu_create(GtkAccelGroup *group) +{ + struct nsgtk_link_menu *nmenu; + + NEW_MENU(nmenu, link); + + IMAGE_ITEM(link, opentab, gtkOpentab, nmenu, group); + IMAGE_ITEM(link, openwin, gtkOpenwin, nmenu, group); + + ADD_SEP(link, nmenu); + + IMAGE_ITEM(link, save, gtkSavelink, nmenu, group); + IMAGE_ITEM(link, bookmark, gtkBookmarklink, nmenu, group); + IMAGE_ITEM(link, copy, gtkCopylink, nmenu, group); return nmenu; } diff --git a/gtk/menu.h b/gtk/menu.h index 681f43c2b..b14c0bb82 100644 --- a/gtk/menu.h +++ b/gtk/menu.h @@ -55,17 +55,13 @@ struct nsgtk_view_menu { GtkImageMenuItem *scaleview_menuitem; struct nsgtk_scaleview_submenu *scaleview_submenu; GtkImageMenuItem *fullscreen_menuitem; - GtkImageMenuItem *viewsource_menuitem; GtkImageMenuItem *images_menuitem; struct nsgtk_images_submenu *images_submenu; GtkImageMenuItem *toolbars_menuitem; struct nsgtk_toolbars_submenu *toolbars_submenu; GtkImageMenuItem *tabs_menuitem; struct nsgtk_tabs_submenu *tabs_submenu; - GtkImageMenuItem *downloads_menuitem; GtkImageMenuItem *savewindowsize_menuitem; - GtkImageMenuItem *debugging_menuitem; - struct nsgtk_debugging_submenu *debugging_submenu; }; struct nsgtk_nav_menu { @@ -78,10 +74,19 @@ struct nsgtk_nav_menu { GtkImageMenuItem *globalhistory_menuitem; GtkImageMenuItem *addbookmarks_menuitem; GtkImageMenuItem *showbookmarks_menuitem; - GtkImageMenuItem *showcookies_menuitem; GtkImageMenuItem *openlocation_menuitem; }; +struct nsgtk_tools_menu { + GtkMenuItem *tools; /* Tools menu item on menubar */ + GtkMenu *tools_menu; + + GtkImageMenuItem *showcookies_menuitem; + GtkImageMenuItem *downloads_menuitem; + GtkImageMenuItem *developer_menuitem; + struct nsgtk_developer_submenu *developer_submenu; +}; + struct nsgtk_help_menu { GtkMenuItem *help; /* Help menu item on menubar */ GtkMenu *help_menu; @@ -91,6 +96,7 @@ struct nsgtk_help_menu { GtkImageMenuItem *about_menuitem; }; + struct nsgtk_export_submenu { GtkMenu *export_menu; GtkImageMenuItem *plaintext_menuitem; @@ -125,11 +131,13 @@ struct nsgtk_toolbars_submenu { GtkCheckMenuItem *toolbar_menuitem; }; -struct nsgtk_debugging_submenu { - GtkMenu *debugging_menu; +struct nsgtk_developer_submenu { + GtkMenu *developer_menu; + + GtkImageMenuItem *viewsource_menuitem; GtkImageMenuItem *toggledebugging_menuitem; - GtkImageMenuItem *saveboxtree_menuitem; - GtkImageMenuItem *savedomtree_menuitem; + GtkImageMenuItem *debugboxtree_menuitem; + GtkImageMenuItem *debugdomtree_menuitem; }; @@ -139,11 +147,12 @@ struct nsgtk_bar_submenu { struct nsgtk_edit_menu *edit_submenu; struct nsgtk_view_menu *view_submenu; struct nsgtk_nav_menu *nav_submenu; - struct nsgtk_tabs_menu *tabs_submenu; + struct nsgtk_tabs_submenu *tabs_submenu; + struct nsgtk_tools_menu *tools_submenu; struct nsgtk_help_menu *help_submenu; }; -struct nsgtk_popup_submenu { +struct nsgtk_popup_menu { GtkMenu *popup_menu; GtkImageMenuItem *file_menuitem; @@ -159,19 +168,16 @@ struct nsgtk_popup_submenu { struct nsgtk_nav_menu *nav_submenu; GtkImageMenuItem *tabs_menuitem; - struct nsgtk_tabs_menu *tabs_submenu; + struct nsgtk_tabs_submenu *tabs_submenu; + + GtkImageMenuItem *tools_menuitem; + struct nsgtk_tools_menu *tools_submenu; GtkImageMenuItem *help_menuitem; struct nsgtk_help_menu *help_submenu; GtkWidget *first_separator; - GtkImageMenuItem *opentab_menuitem; - GtkImageMenuItem *openwin_menuitem; - GtkImageMenuItem *savelink_menuitem; - - GtkWidget *second_separator; - /* navigation entries */ GtkImageMenuItem *back_menuitem; GtkImageMenuItem *forward_menuitem; @@ -189,7 +195,33 @@ struct nsgtk_popup_submenu { }; +struct nsgtk_link_menu { + GtkMenu *link_menu; + + GtkImageMenuItem *opentab_menuitem; + GtkImageMenuItem *openwin_menuitem; + + GtkImageMenuItem *save_menuitem; + GtkImageMenuItem *bookmark_menuitem; + GtkImageMenuItem *copy_menuitem; +}; + +/** + * Create main menu bar. + */ struct nsgtk_bar_submenu *nsgtk_menu_bar_create(GtkMenuShell *menubar, GtkAccelGroup *group); -struct nsgtk_popup_submenu *nsgtk_menu_popup_create(GtkAccelGroup *group); + +/** + * Generate right click menu menu. + * + */ +struct nsgtk_popup_menu *nsgtk_popup_menu_create(GtkAccelGroup *group); + +/** + * Generate context sensitive popup menu for link. + * + */ +struct nsgtk_link_menu *nsgtk_link_menu_create(GtkAccelGroup *group); + #endif diff --git a/gtk/options.h b/gtk/options.h index 612809eac..63f2ad177 100644 --- a/gtk/options.h +++ b/gtk/options.h @@ -65,8 +65,8 @@ NSOPTION_BOOL(new_blank, false) /* path to save hotlist file */ 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/plotters.c b/gtk/plotters.c index 8896da448..b2a7edecc 100644 --- a/gtk/plotters.c +++ b/gtk/plotters.c @@ -33,11 +33,12 @@ #include "utils/log.h" #include "desktop/plotters.h" +#include "render/font.h" +#include "utils/nsoption.h" + #include "gtk/font_pango.h" #include "gtk/plotters.h" #include "gtk/scaffolding.h" -#include "render/font.h" -#include "utils/nsoption.h" #include "gtk/bitmap.h" GtkWidget *current_widget; diff --git a/gtk/res/C/Messages b/gtk/res/C/Messages deleted file mode 120000 index 72c9eff90..000000000 --- a/gtk/res/C/Messages +++ /dev/null @@ -1 +0,0 @@ -../../../!NetSurf/Resources/en/Messages
\ No newline at end of file diff --git a/gtk/res/C/credits.html b/gtk/res/C/credits.html deleted file mode 120000 index 1ba17392b..000000000 --- a/gtk/res/C/credits.html +++ /dev/null @@ -1 +0,0 @@ -../../../!NetSurf/Resources/en/credits.html,faf
\ No newline at end of file diff --git a/gtk/res/C/licence.html b/gtk/res/C/licence.html deleted file mode 120000 index 147dd6db2..000000000 --- a/gtk/res/C/licence.html +++ /dev/null @@ -1 +0,0 @@ -../../../!NetSurf/Resources/en/licence.html,faf
\ No newline at end of file diff --git a/gtk/res/C/welcome.html b/gtk/res/C/welcome.html deleted file mode 120000 index 28362130a..000000000 --- a/gtk/res/C/welcome.html +++ /dev/null @@ -1 +0,0 @@ -../../../!NetSurf/Resources/en/welcome.html,faf
\ No newline at end of file diff --git a/gtk/res/Messages b/gtk/res/Messages new file mode 120000 index 000000000..75bfdf53d --- /dev/null +++ b/gtk/res/Messages @@ -0,0 +1 @@ +en/Messages
\ No newline at end of file diff --git a/gtk/res/SearchEngines b/gtk/res/SearchEngines index e7fd7cb65..38e77957b 100644 --- a/gtk/res/SearchEngines +++ b/gtk/res/SearchEngines @@ -2,15 +2,13 @@ Google|www.google.com|http://www.google.com/search?q=%s|http://www.google.com/fa Yahoo|search.yahoo.com|http://search.yahoo.com/search?p=%s|http://www.yahoo.com/favicon.ico| Bing|www.bing.com|http://www.bing.com/search?q=%s|http://www.bing.com/favicon.ico| Business.com|www.business.com|http://www.business.com/search/rslt_default.asp?query=%s|http://www.business.com/favicon.ico| -Omgili|www.omgili.com|http://www.omgili.com/AAAAA/%s.html|http://www.omgili.com/favicon.ico| -BBC News|search.bbc.co.uk|http://search.bbc.co.uk/search?q=%s&tab=ns|http://news.bbc.co.uk/favicon.ico| +Omgili|www.omgili.com|http://www.omgili.com/AAAAA/%s.html|http://omgili.com/public/images/favicon.ico| +BBC News|search.bbc.co.uk|http://search.bbc.co.uk/search?q=%s&tab=ns|http://www.bbc.co.uk/favicon.ico| Ubuntu Packages|packages.ubuntu.com|http://packages.ubuntu.com/search?keywords=%s|http://packages.ubuntu.com/favicon.ico| -Creative Commons|creativecommons.org|http://creativecommons.org/?s=%s|http://creativecommons.org/favicon.ico| -Ask.com|www.ask.com|http://www.ask.com/web?q=%s|http://www.ask.com/favicon.ico| -Answers.com|www.answers.com|http://www.answers.com/%s|http://www.answers.com/favicon.ico| +Creative Commons|creativecommons.org|http://creativecommons.org/?s=%s|http://creativecommons.org/favicon.ico|fixme:favicon does not work as it is served as x-icon and is a png +Ask.com|www.ask.com|http://www.ask.com/web?q=%s|http://sp.uk.ask.com/sh/i/a14/favicon/favicon.ico|fixme:favicon is served as text/plain Dictionary.com|dictionary.reference.com|http://dictionary.reference.com/browse/%s?jss=0|http://dictionary.reference.com/favicon.ico| Youtube|www.youtube.com|http://www.youtube.com/results?search_query=%s|http://www.youtube.com/favicon.ico| -AeroMp3|www.aeromp3.com|http://www.aeromp3.com/search?q=%s|http://www.aeromp3.com/favicon.ico| AOL|search.aol.com|http://search.aol.com/aol/search?query=%s|http://www.aol.com/favicon.ico| Baidu|www.baidu.com|http://www.baidu.com/s?wd=%s|http://www.baidu.com/favicon.ico| Amazon|www.amazon.com|http://www.amazon.com/s/ref=nb_ss_gw?field-keywords=%s|http://www.amazon.com/favicon.ico| @@ -18,5 +16,5 @@ Ebay|shop.ebay.com|http://shop.ebay.com/items/%s|http://www.ebay.com/favicon.ico IMDB|www.imdb.com|http://www.imdb.com/find?q=%s|http://www.imdb.com/favicon.ico| ESPN|search.espn.go.com|http://search.espn.go.com/%s/|http://www.espn.go.com/favicon.ico| Wikipedia|en.wikipedia.org|http://en.wikipedia.org/w/index.php?title=Special%%3ASearch&search=%s|http://en.wikipedia.org/favicon.ico| -DuckDuckGo|www.duckduckgo.com|http://www.duckduckgo.com/?q=%s|http://www.duckduckgo.com/favicon.ico| -Seeks|www.seeks-project.info|https://www.seeks-project.info/search.php/search?q=%s|http://www.seeks-project.info/search.php/public/images/seek_icon_32x32_transparent.png| +DuckDuckGo|www.duckduckgo.com|http://www.duckduckgo.com/html/?q=%s|http://www.duckduckgo.com/favicon.ico|fixme:Their ico upsets the current implementation +Seeks|www.seeks-project.info|https://www.seeks-project.info/search.php/search?q=%s|http://www.seeks-project.info/search.php/public/images/seek_icon_32x32_transparent.png|fixme:they have no icon diff --git a/gtk/res/credits.html b/gtk/res/credits.html new file mode 120000 index 000000000..ca85d3d27 --- /dev/null +++ b/gtk/res/credits.html @@ -0,0 +1 @@ +en/credits.html
\ No newline at end of file diff --git a/gtk/res/gtkdefault.css b/gtk/res/gtkdefault.css index 9021eedd9..300c13add 100644 --- a/gtk/res/gtkdefault.css +++ b/gtk/res/gtkdefault.css @@ -12,7 +12,7 @@ input { font-size: 95%; border: medium inset #ddd; } input[type=button], input[type=reset], input[type=submit], button { background-color: #ddd; border: medium outset #ddd; } input[type=checkbox], input[type=radio] { font-size: 105%; } -input[type=file] { background-color: #ddd; border: medium inset #ddd; } +input[type=file] { background-color: #ddd; border: medium outset #ddd; } select { background-color: #ddd; border: medium inset #ddd; font-size: 95%; } select:after { border-left:4px ridge #ddd; } diff --git a/gtk/res/licence.html b/gtk/res/licence.html new file mode 120000 index 000000000..86f8c54bf --- /dev/null +++ b/gtk/res/licence.html @@ -0,0 +1 @@ +en/licence.html
\ No newline at end of file diff --git a/gtk/res/options.gtk2.ui b/gtk/res/options.gtk2.ui index 5e24f8942..9c2f5c6d2 100644 --- a/gtk/res/options.gtk2.ui +++ b/gtk/res/options.gtk2.ui @@ -1,22 +1,63 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8"?> <interface> - <!-- interface-requires gtk+ 2.12 --> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy project-wide --> <object class="GtkDialog" id="dialogPreferences"> + <property name="can_focus">False</property> <property name="border_width">5</property> <property name="title" translatable="yes">preferencesTitle</property> <property name="window_position">center-on-parent</property> <property name="destroy_with_parent">True</property> <property name="type_hint">dialog</property> - <property name="has_separator">False</property> - <signal name="destroy" handler="nsgtk_preferences_dialogPreferences_destroy"/> - <signal name="response" handler="nsgtk_preferences_dialogPreferences_response"/> - <signal name="delete_event" handler="nsgtk_preferences_dialogPreferences_deleteevent"/> + <signal name="destroy" handler="nsgtk_preferences_dialogPreferences_destroy" swapped="no"/> + <signal name="delete-event" handler="nsgtk_preferences_dialogPreferences_deleteevent" swapped="no"/> + <signal name="response" handler="nsgtk_preferences_dialogPreferences_response" swapped="no"/> <child internal-child="vbox"> <object class="GtkVBox" id="vbox_dialog"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="layout_style">edge</property> + <child> + <object class="GtkButton" id="help"> + <property name="label">gtk-help</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="close"> + <property name="label">gtk-close</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> <child> <object class="GtkNotebook" id="notebook1"> <property name="visible">True</property> @@ -24,31 +65,35 @@ <child> <object class="GtkVBox" id="vbox_main"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkFrame" id="frame_main_startup"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox2"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkHBox" id="hbox1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkLabel" id="label_startup_page"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesStartupPage</property> </object> <packing> @@ -61,59 +106,69 @@ <object class="GtkEntry" id="entryHomePageURL"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="nsgtk_preferences_entryHomePageURL_changed"/> - <signal name="realize" handler="nsgtk_preferences_entryHomePageURL_realize"/> + <property name="invisible_char">●</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <signal name="changed" handler="nsgtk_preferences_entryHomePageURL_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_entryHomePageURL_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <placeholder/> </child> <child> - <object class="GtkButton" id="setCurrentPage"> - <property name="label" translatable="yes">preferencesStartupPageCurrent</property> + <object class="GtkButton" id="setDefaultPage"> + <property name="label" translatable="yes">preferencesStartupPageDefault</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <signal name="clicked" handler="nsgtk_preferences_setCurrentPage_clicked"/> + <signal name="clicked" handler="nsgtk_preferences_setDefaultPage_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="pack_type">end</property> - <property name="position">2</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkButton" id="setDefaultPage"> - <property name="label" translatable="yes">preferencesStartupPageDefault</property> + <object class="GtkButton" id="setCurrentPage"> + <property name="label" translatable="yes">preferencesStartupPageCurrent</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <signal name="clicked" handler="nsgtk_preferences_setDefaultPage_clicked"/> + <signal name="clicked" handler="nsgtk_preferences_setCurrentPage_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="pack_type">end</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">1</property> </packing> @@ -125,6 +180,7 @@ <child type="label"> <object class="GtkLabel" id="label_main_startup"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesStartup</property> <property name="use_markup">True</property> </object> @@ -132,6 +188,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">0</property> </packing> @@ -139,18 +196,20 @@ <child> <object class="GtkFrame" id="frame_main_search"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkUrlSearch"> @@ -159,20 +218,24 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkUrlSearch_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkUrlSearch_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkUrlSearch_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkUrlSearch_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkLabel" id="label5"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesSearchProvider</property> </object> <packing> @@ -184,9 +247,10 @@ <child> <object class="GtkComboBox" id="comboSearch"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">liststore_search_provider</property> - <signal name="changed" handler="nsgtk_preferences_comboSearch_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboSearch_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboSearch_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboSearch_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext1"/> <attributes> @@ -195,11 +259,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -210,6 +278,7 @@ <child type="label"> <object class="GtkLabel" id="label4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesSearch</property> <property name="use_markup">True</property> </object> @@ -217,6 +286,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">1</property> </packing> @@ -224,18 +294,20 @@ <child> <object class="GtkFrame" id="frame_main_downloads"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox4"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkClearDownloads"> @@ -244,11 +316,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkClearDownloads_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkClearDownloads_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkClearDownloads_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkClearDownloads_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -259,42 +332,50 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkRequestOverwrite_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkRequestOverwrite_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkRequestOverwrite_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkRequestOverwrite_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkHBox" id="hbox4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkLabel" id="label8"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesDownloadsLocation</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkFileChooserButton" id="fileChooserDownloads"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="action">select-folder</property> - <signal name="selection_changed" handler="nsgtk_preferences_fileChooserDownloads_selectionchanged"/> - <signal name="realize" handler="nsgtk_preferences_fileChooserDownloads_realize"/> + <signal name="selection-changed" handler="nsgtk_preferences_fileChooserDownloads_selectionchanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_fileChooserDownloads_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> @@ -305,6 +386,7 @@ <child type="label"> <object class="GtkLabel" id="label7"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesDownloads</property> <property name="use_markup">True</property> </object> @@ -312,6 +394,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">2</property> </packing> @@ -321,6 +404,7 @@ <child type="tab"> <object class="GtkLabel" id="label1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesMainTabtitle</property> </object> <packing> @@ -330,29 +414,33 @@ <child> <object class="GtkVBox" id="vbox_appearance"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkFrame" id="frame_appearance_theme"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkHBox" id="themehbox"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkComboBox" id="comboTheme"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">liststore_themes</property> - <signal name="changed" handler="nsgtk_preferences_comboTheme_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboTheme_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboTheme_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboTheme_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext9"/> <attributes> @@ -361,6 +449,8 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -370,10 +460,11 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <signal name="clicked" handler="nsgtk_preferences_buttonAddTheme_clicked"/> + <signal name="clicked" handler="nsgtk_preferences_buttonAddTheme_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">1</property> </packing> @@ -385,6 +476,7 @@ <child type="label"> <object class="GtkLabel" id="label3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesThemes</property> <property name="use_markup">True</property> </object> @@ -392,6 +484,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">0</property> </packing> @@ -399,18 +492,20 @@ <child> <object class="GtkFrame" id="frame_appearance_tabs"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment5"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox5"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkShowSingleTab"> @@ -419,10 +514,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkShowSingleTab_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkShowSingleTab_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkShowSingleTab_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkShowSingleTab_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -433,10 +530,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkFocusNew_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkFocusNew_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkFocusNew_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkFocusNew_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -447,20 +546,24 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkNewBlank_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkNewBlank_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkNewBlank_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkNewBlank_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkHBox" id="hbox5"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkLabel" id="label9"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesTabsPosition</property> </object> <packing> @@ -472,9 +575,10 @@ <child> <object class="GtkComboBox" id="comboTabPosition"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">liststore_tab_position</property> - <signal name="changed" handler="nsgtk_preferences_comboTabPosition_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboTabPosition_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboTabPosition_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboTabPosition_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext2"/> <attributes> @@ -483,11 +587,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">3</property> </packing> </child> @@ -498,6 +606,7 @@ <child type="label"> <object class="GtkLabel" id="label6"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesTabs</property> <property name="use_markup">True</property> </object> @@ -505,73 +614,71 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">1</property> </packing> </child> <child> - <object class="GtkFrame" id="frame_appearance_source"> + <object class="GtkFrame" id="frame_appearance_tools"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment7"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkLabel" id="label13"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">preferencesSourceOpen</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> <object class="GtkHBox" id="hbox6"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkRadioButton" id="sourceButtonWindow"> - <property name="label" translatable="yes">preferencesSourceWindow</property> + <object class="GtkLabel" id="label13"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <property name="group">sourceButtonTab</property> - <signal name="realize" handler="nsgtk_preferences_sourceButtonWindow_realize"/> - <signal name="toggled" handler="nsgtk_preferences_sourceButtonWindow_toggled"/> + <property name="can_focus">False</property> + <property name="label" translatable="yes">preferencesDeveloperView</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkRadioButton" id="sourceButtonTab"> - <property name="label" translatable="yes">preferencesSourceTab</property> + <object class="GtkComboBox" id="comboboxDeveloperView"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_sourceButtonTab_realize"/> - <signal name="toggled" handler="nsgtk_preferences_sourceButtonTab_toggled"/> + <property name="can_focus">False</property> + <property name="model">liststore_developer_view</property> + <signal name="changed" handler="nsgtk_preferences_comboDeveloperView_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboDeveloperView_realize" swapped="no"/> + <child> + <object class="GtkCellRendererText" id="cellrenderertext10"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="position">1</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> </object> @@ -581,13 +688,15 @@ <child type="label"> <object class="GtkLabel" id="label12"> <property name="visible">True</property> - <property name="label" translatable="yes">preferencesSource</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">preferencesTools</property> <property name="use_markup">True</property> </object> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">2</property> </packing> @@ -595,18 +704,20 @@ <child> <object class="GtkFrame" id="frame_appearance_url"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment8"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox7"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkDisplayRecentURLs"> @@ -615,10 +726,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkDisplayRecentURLs_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkDisplayRecentURLs_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkDisplayRecentURLs_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkDisplayRecentURLs_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -629,6 +742,7 @@ <child type="label"> <object class="GtkLabel" id="label14"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesURLbar</property> <property name="use_markup">True</property> </object> @@ -636,6 +750,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">7</property> <property name="position">3</property> </packing> @@ -643,39 +758,45 @@ <child> <object class="GtkFrame" id="frame_appearance_toolbar"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment9"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox8"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkHBox" id="hbox7"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label16"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesToolbarButtons</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkComboBox" id="comboButtonType"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">liststore_toolbar_buttontype</property> - <signal name="changed" handler="nsgtk_preferences_comboButtonType_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboButtonType_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboButtonType_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboButtonType_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext3"/> <attributes> @@ -684,11 +805,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -699,6 +824,7 @@ <child type="label"> <object class="GtkLabel" id="label15"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesToolbar</property> <property name="use_markup">True</property> </object> @@ -706,6 +832,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">4</property> </packing> @@ -718,6 +845,7 @@ <child type="tab"> <object class="GtkLabel" id="label2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesAppearanceTabtitle</property> </object> <packing> @@ -728,23 +856,25 @@ <child> <object class="GtkVBox" id="vbox_content"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkFrame" id="frame_content_control"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment6"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox6"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkDisablePopups"> @@ -753,8 +883,8 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkDisablePopups_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkDisablePopups_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkDisablePopups_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkDisablePopups_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -769,8 +899,8 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkHideAdverts_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkHideAdverts_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkHideAdverts_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkHideAdverts_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -785,8 +915,8 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkEnableJavascript_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkEnableJavascript_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkEnableJavascript_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkEnableJavascript_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -801,8 +931,8 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkDisablePlugins_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkDisablePlugins_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkDisablePlugins_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkDisablePlugins_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -817,33 +947,39 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkResampleImages_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkResampleImages_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkResampleImages_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkResampleImages_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">4</property> </packing> </child> <child> <object class="GtkHBox" id="hbox8"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label17"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesControlLoad</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkComboBox" id="comboboxLoadImages"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">liststore_image_loading</property> - <signal name="changed" handler="nsgtk_preferences_comboboxLoadImages_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboboxLoadImages_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboboxLoadImages_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboboxLoadImages_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext4"/> <attributes> @@ -852,11 +988,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">5</property> </packing> </child> @@ -867,6 +1007,7 @@ <child type="label"> <object class="GtkLabel" id="label11"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesControl</property> <property name="use_markup">True</property> </object> @@ -874,6 +1015,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">0</property> </packing> @@ -881,18 +1023,20 @@ <child> <object class="GtkFrame" id="frame_content_animation"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment10"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox9"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkEnableAnimations"> @@ -901,24 +1045,29 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkEnableAnimations_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkEnableAnimations_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkEnableAnimations_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkEnableAnimations_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox9"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkLabel" id="label19"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesAnimationMinimum</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -928,22 +1077,29 @@ <property name="can_focus">True</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesAnimationMinimumTooltip</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_animation_time</property> <property name="climb_rate">1</property> <property name="digits">1</property> <property name="numeric">True</property> <property name="update_policy">if-valid</property> - <signal name="value_changed" handler="nsgtk_preferences_spinAnimationSpeed_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinAnimationSpeed_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinAnimationSpeed_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinAnimationSpeed_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -954,6 +1110,7 @@ <child type="label"> <object class="GtkLabel" id="label18"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesAnimation</property> <property name="use_markup">True</property> </object> @@ -961,6 +1118,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">1</property> </packing> @@ -968,38 +1126,45 @@ <child> <object class="GtkFrame" id="frame_content_fonts"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment14"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkHBox" id="hbox11"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkHBox" id="hbox12"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label26"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesFontsDefault</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkComboBox" id="comboDefault"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">liststore_defaultfont</property> - <signal name="changed" handler="nsgtk_preferences_comboDefault_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboDefault_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboDefault_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboDefault_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext5"/> <attributes> @@ -1008,25 +1173,32 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox13"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label27"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesFontsSize</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -1037,23 +1209,29 @@ <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesFontsSizeTooltip</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_font_default_size</property> <property name="climb_rate">1</property> <property name="digits">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinDefaultSize_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinDefaultSize_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinDefaultSize_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinDefaultSize_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -1065,10 +1243,11 @@ <property name="receives_default">True</property> <property name="image">image1</property> <property name="use_underline">True</property> - <signal name="clicked" handler="nsgtk_preferences_fontPreview_clicked"/> + <signal name="clicked" handler="nsgtk_preferences_fontPreview_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> @@ -1079,6 +1258,7 @@ <child type="label"> <object class="GtkLabel" id="label20"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesFonts</property> <property name="use_markup">True</property> </object> @@ -1086,47 +1266,54 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkFrame" id="frame_content_font"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment11"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox10"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkHBox" id="hbox10"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkLabel" id="label21"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesLanguagePreferred</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkComboBox" id="comboboxLanguage"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesLanguagePreferredTooltip</property> <property name="model">liststore_content_language</property> - <signal name="changed" handler="nsgtk_preferences_comboboxLanguage_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboboxLanguage_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboboxLanguage_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboboxLanguage_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext7"> <property name="xalign">0</property> @@ -1145,11 +1332,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -1160,6 +1351,7 @@ <child type="label"> <object class="GtkLabel" id="label25"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesLanguage</property> <property name="use_markup">True</property> </object> @@ -1167,6 +1359,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">3</property> </packing> </child> @@ -1178,6 +1371,7 @@ <child type="tab"> <object class="GtkLabel" id="label10"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesContentTabtitle</property> </object> <packing> @@ -1188,23 +1382,25 @@ <child> <object class="GtkVBox" id="vbox_privacy"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkFrame" id="frame_privacy_general"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment20"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox15"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkSendReferer"> @@ -1213,10 +1409,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkSendReferer_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkSendReferer_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkSendReferer_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkSendReferer_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -1227,10 +1425,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkSendDNT_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkSendDNT_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkSendDNT_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkSendDNT_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -1241,6 +1441,7 @@ <child type="label"> <object class="GtkLabel" id="label61"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesGeneral</property> <property name="use_markup">True</property> </object> @@ -1248,6 +1449,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">0</property> </packing> @@ -1255,18 +1457,20 @@ <child> <object class="GtkFrame" id="frame_privacy_history"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment12"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox11"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkHoverURLs"> @@ -1275,24 +1479,29 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkHoverURLs_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkHoverURLs_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkHoverURLs_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkHoverURLs_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox14"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label28"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesHistoryRemember</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -1301,32 +1510,41 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_history_age</property> <property name="climb_rate">1</property> <property name="numeric">True</property> <property name="update_policy">if-valid</property> - <signal name="value_changed" handler="nsgtk_preferences_spinHistoryAge_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinHistoryAge_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinHistoryAge_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinHistoryAge_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkLabel" id="label29"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesHistoryDays</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -1337,6 +1555,7 @@ <child type="label"> <object class="GtkLabel" id="label23"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesHistory</property> <property name="use_markup">True</property> </object> @@ -1344,6 +1563,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">1</property> </packing> @@ -1351,22 +1571,25 @@ <child> <object class="GtkFrame" id="frame_privacy_cache"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment13"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox12"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkTable" id="table3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">3</property> <property name="n_columns">3</property> <property name="column_spacing">6</property> @@ -1374,6 +1597,7 @@ <child> <object class="GtkLabel" id="label30"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesCacheMemory</property> </object> @@ -1384,6 +1608,7 @@ <child> <object class="GtkLabel" id="label31"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesCacheDisc</property> </object> @@ -1396,6 +1621,7 @@ <child> <object class="GtkLabel" id="label34"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesCacheExpire</property> </object> @@ -1409,13 +1635,17 @@ <object class="GtkSpinButton" id="spinMemoryCacheSize"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_cache_memory_size</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinMemoryCacheSize_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinMemoryCacheSize_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinMemoryCacheSize_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinMemoryCacheSize_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1427,13 +1657,17 @@ <object class="GtkSpinButton" id="spinDiscCacheSize"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_cache_disc_size</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinDiscCacheSize_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinDiscCacheSize_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinDiscCacheSize_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinDiscCacheSize_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1447,13 +1681,17 @@ <object class="GtkSpinButton" id="spinDiscCacheAge"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">3</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_disc_cache_age</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinDiscCacheAge_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinDiscCacheAge_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinDiscCacheAge_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinDiscCacheAge_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1466,8 +1704,9 @@ <child> <object class="GtkLabel" id="label32"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> - <property name="label" translatable="no">MB</property> + <property name="label">MB</property> </object> <packing> <property name="left_attach">2</property> @@ -1478,8 +1717,9 @@ <child> <object class="GtkLabel" id="label33"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> - <property name="label" translatable="no">MB</property> + <property name="label">MB</property> </object> <packing> <property name="left_attach">2</property> @@ -1492,6 +1732,7 @@ <child> <object class="GtkLabel" id="label35"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesHistoryDays</property> </object> @@ -1505,12 +1746,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox17"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> <placeholder/> </child> @@ -1523,11 +1767,14 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -1538,6 +1785,7 @@ <child type="label"> <object class="GtkLabel" id="label24"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesCache</property> <property name="use_markup">True</property> </object> @@ -1545,6 +1793,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">2</property> </packing> @@ -1557,6 +1806,7 @@ <child type="tab"> <object class="GtkLabel" id="label22"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesPrivacyTabtitle</property> </object> <packing> @@ -1567,29 +1817,33 @@ <child> <object class="GtkVBox" id="vbox_network"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkFrame" id="frame_network_proxy"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment15"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkTable" id="table2"> <property name="visible">True</property> - <property name="n_rows">4</property> + <property name="can_focus">False</property> + <property name="n_rows">5</property> <property name="n_columns">2</property> <property name="column_spacing">6</property> <property name="row_spacing">6</property> <child> <object class="GtkLabel" id="label42"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesProxyType</property> </object> @@ -1600,6 +1854,7 @@ <child> <object class="GtkLabel" id="label43"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesProxyHost</property> </object> @@ -1612,6 +1867,7 @@ <child> <object class="GtkLabel" id="label44"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesProxyUsername</property> </object> @@ -1624,6 +1880,7 @@ <child> <object class="GtkLabel" id="label45"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesProxyPassword</property> </object> @@ -1636,11 +1893,12 @@ <child> <object class="GtkComboBox" id="comboProxyType"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesProxyTypeTooltip</property> <property name="model">liststore_proxy_type</property> - <signal name="changed" handler="nsgtk_preferences_comboProxyType_changed"/> - <signal name="realize" handler="nsgtk_preferences_comboProxyType_realize"/> + <signal name="changed" handler="nsgtk_preferences_comboProxyType_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboProxyType_realize" swapped="no"/> <child> <object class="GtkCellRendererText" id="cellrenderertext6"/> <attributes> @@ -1656,6 +1914,7 @@ <child> <object class="GtkHBox" id="hbox19"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkEntry" id="entryProxyHost"> @@ -1663,21 +1922,29 @@ <property name="can_focus">True</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesProxyHostTooltip</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="nsgtk_preferences_entryProxyHost_changed"/> - <signal name="realize" handler="nsgtk_preferences_entryProxyHost_realize"/> + <property name="invisible_char">●</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <signal name="changed" handler="nsgtk_preferences_entryProxyHost_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_entryProxyHost_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkLabel" id="label46"> <property name="visible">True</property> - <property name="label" translatable="no">:</property> + <property name="can_focus">False</property> + <property name="label">:</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -1688,17 +1955,22 @@ <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesProxyPortTooltip</property> <property name="max_length">5</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_proxy_port</property> <property name="climb_rate">1</property> <property name="numeric">True</property> <property name="update_policy">if-valid</property> - <signal name="value_changed" handler="nsgtk_preferences_spinProxyPort_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinProxyPort_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinProxyPort_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinProxyPort_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> @@ -1716,9 +1988,13 @@ <property name="can_focus">True</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesProxyUsernameTooltip</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="nsgtk_preferences_entryProxyUser_changed"/> - <signal name="realize" handler="nsgtk_preferences_entryProxyUser_realize"/> + <property name="invisible_char">●</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <signal name="changed" handler="nsgtk_preferences_entryProxyUser_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_entryProxyUser_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1734,9 +2010,13 @@ <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesProxyPasswordTooltip</property> <property name="visibility">False</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="nsgtk_preferences_entryProxyPassword_changed"/> - <signal name="realize" handler="nsgtk_preferences_entryProxyPassword_realize"/> + <property name="invisible_char">●</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <signal name="changed" handler="nsgtk_preferences_entryProxyPassword_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_entryProxyPassword_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1745,6 +2025,40 @@ <property name="bottom_attach">4</property> </packing> </child> + <child> + <object class="GtkLabel" id="label55"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">preferencesProxyNoproxy</property> + </object> + <packing> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entryProxyNoproxy"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_text" translatable="yes">preferencesProxyNoproxyTooltip</property> + <property name="caps_lock_warning">False</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <signal name="changed" handler="nsgtk_preferences_entryProxyNoproxy_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_entryProxyNoproxy_realize" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + </packing> + </child> </object> </child> </object> @@ -1752,6 +2066,7 @@ <child type="label"> <object class="GtkLabel" id="label37"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesProxy</property> <property name="use_markup">True</property> </object> @@ -1759,6 +2074,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">0</property> </packing> @@ -1766,17 +2082,20 @@ <child> <object class="GtkFrame" id="frame_network_fetching"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment16"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkTable" id="table1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">3</property> <property name="n_columns">2</property> <property name="column_spacing">6</property> @@ -1784,6 +2103,7 @@ <child> <object class="GtkLabel" id="label39"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesFetchingMax</property> </object> @@ -1794,6 +2114,7 @@ <child> <object class="GtkLabel" id="label40"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesFetchingPerhost</property> </object> @@ -1806,6 +2127,7 @@ <child> <object class="GtkLabel" id="label41"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">preferencesFetchingCached</property> </object> @@ -1821,13 +2143,17 @@ <property name="can_focus">True</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesFetchingMaxTooltip</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">3</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_fetching_max</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinMaxFetchers_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinMaxFetchers_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinMaxFetchers_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinMaxFetchers_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1841,13 +2167,17 @@ <property name="can_focus">True</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesFetchingPerhostTooltip</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">3</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_fetching_perhost</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinFetchesPerHost_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinFetchesPerHost_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinFetchesPerHost_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinFetchesPerHost_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1863,13 +2193,17 @@ <property name="can_focus">True</property> <property name="has_tooltip">True</property> <property name="tooltip_text" translatable="yes">preferencesFetchingCachedTooltip.</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">3</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_fetching_cached</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinCachedConnections_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinCachedConnections_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinCachedConnections_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinCachedConnections_realize" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -1886,6 +2220,7 @@ <child type="label"> <object class="GtkLabel" id="label38"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesFetching</property> <property name="use_markup">True</property> </object> @@ -1893,6 +2228,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">1</property> </packing> @@ -1905,6 +2241,7 @@ <child type="tab"> <object class="GtkLabel" id="label36"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesNetworkTabtitle</property> </object> <packing> @@ -1915,23 +2252,25 @@ <child> <object class="GtkVBox" id="vbox_pdfexport"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkFrame" id="frame_pdfexport_appearance"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment17"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox13"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="checkSuppressImages"> @@ -1940,10 +2279,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkSuppressImages_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkSuppressImages_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkSuppressImages_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkSuppressImages_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -1954,10 +2295,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkRemoveBackgrounds_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkRemoveBackgrounds_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkRemoveBackgrounds_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkRemoveBackgrounds_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -1968,24 +2311,29 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkFitPage_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkFitPage_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkFitPage_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkFitPage_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkHBox" id="hbox15"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label59"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesAppearanceScale</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -1994,32 +2342,41 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">4</property> <property name="xalign">1</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_pdf_scale</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinExportScale_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinExportScale_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinExportScale_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinExportScale_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkLabel" id="label60"> <property name="visible">True</property> - <property name="label" translatable="no">%</property> + <property name="can_focus">False</property> + <property name="label">%</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">3</property> </packing> </child> @@ -2030,6 +2387,7 @@ <child type="label"> <object class="GtkLabel" id="label48"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesAppearance</property> <property name="use_markup">True</property> </object> @@ -2037,6 +2395,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">0</property> </packing> @@ -2044,29 +2403,34 @@ <child> <object class="GtkFrame" id="frame_pdfexport_margins"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment18"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox16"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkHBox" id="hbox22"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> <object class="GtkLabel" id="label62"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesMarginsMeasurements</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -2075,25 +2439,40 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkTable" id="table4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">3</property> <property name="n_columns">3</property> <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> <object class="GtkHBox" id="hbox16"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label51"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Top</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -2102,17 +2481,22 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> <property name="xalign">1</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="climb_rate">1</property> <property name="digits">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinMarginTop_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinMarginTop_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinMarginTop_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinMarginTop_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2126,14 +2510,17 @@ <child> <object class="GtkHBox" id="hbox18"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label52"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Left</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -2142,18 +2529,23 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> <property name="xalign">1</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="adjustment">adjustment_pdf_lmargin</property> <property name="climb_rate">1</property> <property name="digits">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinMarginLeft_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinMarginLeft_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinMarginLeft_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinMarginLeft_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2167,14 +2559,17 @@ <child> <object class="GtkHBox" id="hbox20"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label53"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Bottom</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -2183,17 +2578,22 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> <property name="xalign">1</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="climb_rate">1</property> <property name="digits">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinMarginBottom_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinMarginBottom_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinMarginBottom_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinMarginBottom_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2209,14 +2609,17 @@ <child> <object class="GtkHBox" id="hbox21"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="label54"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Right</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -2225,17 +2628,22 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="max_length">4</property> - <property name="invisible_char">●</property> + <property name="invisible_char">●</property> <property name="width_chars">5</property> <property name="xalign">1</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> <property name="climb_rate">1</property> <property name="digits">1</property> <property name="numeric">True</property> - <signal name="value_changed" handler="nsgtk_preferences_spinMarginRight_valuechanged"/> - <signal name="realize" handler="nsgtk_preferences_spinMarginRight_realize"/> + <signal name="value-changed" handler="nsgtk_preferences_spinMarginRight_valuechanged" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_spinMarginRight_realize" swapped="no"/> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2248,23 +2656,10 @@ <property name="x_options">GTK_EXPAND</property> </packing> </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2275,6 +2670,7 @@ <child type="label"> <object class="GtkLabel" id="label49"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesMargins</property> <property name="use_markup">True</property> </object> @@ -2282,6 +2678,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">1</property> </packing> @@ -2289,18 +2686,20 @@ <child> <object class="GtkFrame" id="frame_pdfexport_generation"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> <object class="GtkAlignment" id="alignment19"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <property name="right_padding">12</property> <child> <object class="GtkVBox" id="vbox14"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">7</property> <child> <object class="GtkCheckButton" id="checkCompressPDF"> @@ -2309,10 +2708,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkCompressPDF_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkCompressPDF_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkCompressPDF_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkCompressPDF_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -2323,10 +2724,12 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="draw_indicator">True</property> - <signal name="realize" handler="nsgtk_preferences_checkPasswordPDF_realize"/> - <signal name="toggled" handler="nsgtk_preferences_checkPasswordPDF_toggled"/> + <signal name="toggled" handler="nsgtk_preferences_checkPasswordPDF_toggled" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_checkPasswordPDF_realize" swapped="no"/> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2337,6 +2740,7 @@ <child type="label"> <object class="GtkLabel" id="label50"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesGeneration</property> <property name="use_markup">True</property> </object> @@ -2344,6 +2748,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="padding">6</property> <property name="position">2</property> </packing> @@ -2356,6 +2761,7 @@ <child type="tab"> <object class="GtkLabel" id="label47"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">preferencesPDFTabtitle</property> </object> <packing> @@ -2365,48 +2771,11 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">edge</property> - <child> - <object class="GtkButton" id="help"> - <property name="label">gtk-help</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="close"> - <property name="label">gtk-close</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> </object> </child> <action-widgets> @@ -2421,67 +2790,67 @@ </columns> <data> <row> - <col id="0" translatable="no">Google</col> + <col id="0">Google</col> </row> <row> - <col id="0" translatable="no">Yahoo!</col> + <col id="0">Yahoo!</col> </row> <row> - <col id="0" translatable="no">Microsoft Live</col> + <col id="0">Microsoft Live</col> </row> <row> - <col id="0" translatable="no">Buisiness.com</col> + <col id="0">Buisiness.com</col> </row> <row> - <col id="0" translatable="no">Omgili</col> + <col id="0">Omgili</col> </row> <row> - <col id="0" translatable="no">BBC News</col> + <col id="0">BBC News</col> </row> <row> - <col id="0" translatable="no">Ubuntu Packages</col> + <col id="0">Ubuntu Packages</col> </row> <row> - <col id="0" translatable="no">Creative Commons</col> + <col id="0">Creative Commons</col> </row> <row> - <col id="0" translatable="no">Ask</col> + <col id="0">Ask</col> </row> <row> - <col id="0" translatable="no">Answers</col> + <col id="0">Answers</col> </row> <row> - <col id="0" translatable="no">Dictionary.com</col> + <col id="0">Dictionary.com</col> </row> <row> - <col id="0" translatable="no">YouTube</col> + <col id="0">YouTube</col> </row> <row> - <col id="0" translatable="no">AeroMP3</col> + <col id="0">AeroMP3</col> </row> <row> - <col id="0" translatable="no">AOL</col> + <col id="0">AOL</col> </row> <row> - <col id="0" translatable="no">Baidu</col> + <col id="0">Baidu</col> </row> <row> - <col id="0" translatable="no">Amazon</col> + <col id="0">Amazon</col> </row> <row> - <col id="0" translatable="no">Ebay</col> + <col id="0">Ebay</col> </row> <row> - <col id="0" translatable="no">IMBD</col> + <col id="0">IMBD</col> </row> <row> - <col id="0" translatable="no">ESPN</col> + <col id="0">ESPN</col> </row> <row> - <col id="0" translatable="no">Wikipedia</col> + <col id="0">Wikipedia</col> </row> <row> - <col id="0" translatable="no">DuckDuckGo</col> + <col id="0">DuckDuckGo</col> </row> </data> </object> @@ -2570,6 +2939,7 @@ </object> <object class="GtkImage" id="image1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xpad">3</property> <property name="stock">gtk-apply</property> </object> @@ -2623,10 +2993,10 @@ <property name="page_increment">16</property> </object> <object class="GtkAdjustment" id="adjustment_cache_disc_size"> - <property name="value">16</property> - <property name="upper">2048</property> - <property name="step_increment">4</property> - <property name="page_increment">16</property> + <property name="value">1024</property> + <property name="upper">4096</property> + <property name="step_increment">32</property> + <property name="page_increment">256</property> </object> <object class="GtkAdjustment" id="adjustment_disc_cache_age"> <property name="value">28</property> @@ -2698,4 +3068,21 @@ </row> </data> </object> + <object class="GtkListStore" id="liststore_developer_view"> + <columns> + <!-- column-name Type --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">preferencesDeveloperViewWindow</col> + </row> + <row> + <col id="0" translatable="yes">preferencesDeveloperViewTab</col> + </row> + <row> + <col id="0" translatable="yes">preferencesDeveloperViewEditor</col> + </row> + </data> + </object> </interface> diff --git a/gtk/res/options.gtk3.ui b/gtk/res/options.gtk3.ui index a795c2bf5..ac435834a 100644 --- a/gtk/res/options.gtk3.ui +++ b/gtk/res/options.gtk3.ui @@ -9,13 +9,13 @@ <property name="page_increment">1</property> </object> <object class="GtkAdjustment" id="adjustment_cache_disc_size"> - <property name="upper">2048</property> - <property name="value">16</property> + <property name="upper">4096</property> + <property name="value">1024</property> <property name="step_increment">4</property> <property name="page_increment">16</property> </object> <object class="GtkAdjustment" id="adjustment_cache_memory_size"> - <property name="upper">2048</property> + <property name="upper">1024</property> <property name="value">16</property> <property name="step_increment">4</property> <property name="page_increment">16</property> @@ -736,7 +736,7 @@ </packing> </child> <child> - <object class="GtkFrame" id="frame_appearance_source"> + <object class="GtkFrame" id="frame_appearance_tools"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label_xalign">0</property> @@ -754,58 +754,36 @@ <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkLabel" id="label13"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">preferencesSourceOpen</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> <object class="GtkHBox" id="hbox6"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="spacing">12</property> <child> - <object class="GtkRadioButton" id="sourceButtonWindow"> - <property name="label" translatable="yes">preferencesSourceWindow</property> - <property name="use_action_appearance">False</property> + <object class="GtkLabel" id="label13"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_action_appearance">False</property> - <property name="xalign">0.5</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <property name="group">sourceButtonTab</property> - <signal name="toggled" handler="nsgtk_preferences_sourceButtonWindow_toggled" swapped="no"/> - <signal name="realize" handler="nsgtk_preferences_sourceButtonWindow_realize" swapped="no"/> + <property name="can_focus">False</property> + <property name="label" translatable="yes">preferencesDeveloperView</property> </object> <packing> - <property name="expand">True</property> + <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkRadioButton" id="sourceButtonTab"> - <property name="label" translatable="yes">preferencesSourceTab</property> - <property name="use_action_appearance">False</property> + <object class="GtkComboBox" id="comboboxDeveloperView"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> + <property name="can_focus">False</property> <property name="halign">start</property> - <property name="use_action_appearance">False</property> - <property name="xalign">0.5</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="nsgtk_preferences_sourceButtonTab_toggled" swapped="no"/> - <signal name="realize" handler="nsgtk_preferences_sourceButtonTab_realize" swapped="no"/> + <property name="model">liststore_developer_view</property> + <signal name="changed" handler="nsgtk_preferences_comboDeveloperView_changed" swapped="no"/> + <signal name="realize" handler="nsgtk_preferences_comboDeveloperView_realize" swapped="no"/> + <child> + <object class="GtkCellRendererText" id="cellrenderertext10"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> </object> <packing> <property name="expand">True</property> @@ -828,7 +806,7 @@ <object class="GtkLabel" id="label12"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">preferencesSource</property> + <property name="label" translatable="yes">preferencesTools</property> <property name="use_markup">True</property> </object> </child> @@ -2982,6 +2960,23 @@ </row> </data> </object> + <object class="GtkListStore" id="liststore_developer_view"> + <columns> + <!-- column-name Type --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">preferencesDeveloperViewWindow</col> + </row> + <row> + <col id="0" translatable="yes">preferencesDeveloperViewTab</col> + </row> + <row> + <col id="0" translatable="yes">preferencesDeveloperViewEditor</col> + </row> + </data> + </object> <object class="GtkListStore" id="liststore_image_loading"> <columns> <!-- column-name Type --> 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/res/welcome.html b/gtk/res/welcome.html new file mode 120000 index 000000000..1abdc5e8a --- /dev/null +++ b/gtk/res/welcome.html @@ -0,0 +1 @@ +en/welcome.html
\ No newline at end of file diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index b39283cc6..93cd7f768 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -18,26 +18,23 @@ */ #include <assert.h> -#include <dirent.h> #include <stdbool.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <errno.h> -#include <unistd.h> +#include <stdlib.h> #include <gtk/gtk.h> #include <gdk-pixbuf/gdk-pixbuf.h> -#include "gtk/scaffolding.h" -#include "content/content.h" -#include "content/hlcache.h" -#include "css/utils.h" -#include "desktop/browser_private.h" -#include "desktop/local_history.h" +#include "utils/filepath.h" +#include "utils/messages.h" +#include "utils/url.h" +#include "utils/log.h" +#include "utils/nsoption.h" +#include "utils/file.h" +#include "desktop/browser_history.h" +#include "desktop/browser.h" #include "desktop/hotlist.h" -#include "desktop/gui.h" #include "desktop/netsurf.h" -#include "utils/nsoption.h" #include "desktop/plotters.h" #include "desktop/print.h" #include "desktop/save_complete.h" @@ -46,60 +43,51 @@ #include "desktop/save_pdf/pdf_plotters.h" #endif #include "desktop/save_text.h" -#include "desktop/search.h" #include "desktop/searchweb.h" #include "desktop/textinput.h" -#include "desktop/tree.h" +#include "render/font.h" +#include "render/html.h" +#include "content/hlcache.h" + +#include "gtk/compat.h" #include "gtk/cookies.h" #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/download.h" #include "gtk/gui.h" #include "gtk/history.h" #include "gtk/hotlist.h" +#include "gtk/download.h" #include "gtk/menu.h" #include "gtk/plotters.h" #include "gtk/print.h" -#include "gtk/schedule.h" #include "gtk/search.h" -#include "gtk/tabs.h" #include "gtk/theme.h" #include "gtk/throbber.h" #include "gtk/toolbar.h" -#include "gtk/treeview.h" #include "gtk/window.h" -#include "gtk/compat.h" #include "gtk/gdk.h" -#include "image/ico.h" -#include "render/font.h" -#include "render/form.h" -#include "render/html.h" -#include "utils/messages.h" -#include "utils/schedule.h" -#include "utils/utils.h" -#include "utils/url.h" - -#include "utils/log.h" - - +#include "gtk/scaffolding.h" +#include "gtk/tabs.h" +#include "gtk/schedule.h" +#include "gtk/viewdata.h" /** Macro to define a handler for menu, button and activate events. */ #define MULTIHANDLER(q)\ -static gboolean nsgtk_on_##q##_activate(struct gtk_scaffolding *g);\ +static gboolean nsgtk_on_##q##_activate(struct nsgtk_scaffolding *g);\ static gboolean nsgtk_on_##q##_activate_menu(GtkMenuItem *widget, gpointer data)\ {\ - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;\ + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;\ return nsgtk_on_##q##_activate(g);\ }\ static gboolean nsgtk_on_##q##_activate_button(GtkButton *widget, gpointer data)\ {\ - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;\ + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;\ return nsgtk_on_##q##_activate(g);\ }\ -static gboolean nsgtk_on_##q##_activate(struct gtk_scaffolding *g) +static gboolean nsgtk_on_##q##_activate(struct nsgtk_scaffolding *g) /** Macro to define a handler for menu events. */ #define MENUHANDLER(q)\ @@ -110,7 +98,7 @@ static gboolean nsgtk_on_##q##_activate_menu(GtkMenuItem *widget, gpointer data) static gboolean nsgtk_on_##q##_activate(GtkButton *widget, gpointer data) /** Core scaffolding structure. */ -struct gtk_scaffolding { +struct nsgtk_scaffolding { GtkWindow *window; GtkNotebook *notebook; GtkWidget *url_bar; @@ -120,7 +108,10 @@ struct gtk_scaffolding { struct nsgtk_bar_submenu *menu_bar; /** right click popup menu hierarchy */ - struct nsgtk_popup_submenu *menu_popup; + struct nsgtk_popup_menu *menu_popup; + + /** link popup menu */ + struct nsgtk_link_menu *link_menu; GtkToolbar *tool_bar; struct nsgtk_button_connect *buttons[PLACEHOLDER_BUTTON]; @@ -143,14 +134,14 @@ struct gtk_scaffolding { bool fullscreen; /* keep global linked list for gui interface adjustments */ - struct gtk_scaffolding *next, *prev; + struct nsgtk_scaffolding *next, *prev; }; -/** current window for model dialogue use */ -static struct gtk_scaffolding *current_model; +/** current scaffold for model dialogue use */ +static struct nsgtk_scaffolding *scaf_current; /** global list for interface changes */ -nsgtk_scaffolding *scaf_list = NULL; +static struct nsgtk_scaffolding *scaf_list = NULL; /** holds the context data for what's under the pointer, when the contextual * menu is opened. */ @@ -160,8 +151,8 @@ static struct contextual_content current_menu_ctx; /** * Helper to hide popup menu entries by grouping */ -static void popup_menu_hide(struct nsgtk_popup_submenu *menu, bool submenu, - bool link, bool nav, bool cnp, bool custom) +static void popup_menu_hide(struct nsgtk_popup_menu *menu, bool submenu, + bool nav, bool cnp, bool custom) { if (submenu){ gtk_widget_hide(GTK_WIDGET(menu->file_menuitem)); @@ -173,14 +164,6 @@ static void popup_menu_hide(struct nsgtk_popup_submenu *menu, bool submenu, gtk_widget_hide(menu->first_separator); } - if (link) { - gtk_widget_hide(GTK_WIDGET(menu->opentab_menuitem)); - gtk_widget_hide(GTK_WIDGET(menu->openwin_menuitem)); - gtk_widget_hide(GTK_WIDGET(menu->savelink_menuitem)); - - gtk_widget_hide(menu->second_separator); - } - if (nav) { gtk_widget_hide(GTK_WIDGET(menu->back_menuitem)); gtk_widget_hide(GTK_WIDGET(menu->forward_menuitem)); @@ -203,8 +186,8 @@ static void popup_menu_hide(struct nsgtk_popup_submenu *menu, bool submenu, /** * Helper to show popup menu entries by grouping */ -static void popup_menu_show(struct nsgtk_popup_submenu *menu, bool submenu, - bool link, bool nav, bool cnp, bool custom) +static void popup_menu_show(struct nsgtk_popup_menu *menu, bool submenu, + bool nav, bool cnp, bool custom) { if (submenu){ gtk_widget_show(GTK_WIDGET(menu->file_menuitem)); @@ -216,14 +199,6 @@ static void popup_menu_show(struct nsgtk_popup_submenu *menu, bool submenu, gtk_widget_show(menu->first_separator); } - if (link) { - gtk_widget_show(GTK_WIDGET(menu->opentab_menuitem)); - gtk_widget_show(GTK_WIDGET(menu->openwin_menuitem)); - gtk_widget_show(GTK_WIDGET(menu->savelink_menuitem)); - - gtk_widget_show(menu->second_separator); - } - if (nav) { gtk_widget_show(GTK_WIDGET(menu->back_menuitem)); gtk_widget_show(GTK_WIDGET(menu->forward_menuitem)); @@ -251,7 +226,7 @@ static void popup_menu_show(struct nsgtk_popup_submenu *menu, bool submenu, */ static void scaffolding_window_destroy(GtkWidget *widget, gpointer data) { - struct gtk_scaffolding *gs = data; + struct nsgtk_scaffolding *gs = data; LOG(("scaffold:%p", gs)); @@ -282,7 +257,7 @@ static void scaffolding_window_destroy(GtkWidget *widget, gpointer data) static gboolean scaffolding_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { - struct gtk_scaffolding *g = data; + struct nsgtk_scaffolding *g = data; if (nsgtk_check_for_downloads(GTK_WINDOW(widget)) == false) { gtk_widget_destroy(GTK_WIDGET(g->window)); @@ -290,42 +265,28 @@ static gboolean scaffolding_window_delete_event(GtkWidget *widget, return TRUE; } -/* exported interface documented in gtk_scaffold.h */ -void nsgtk_scaffolding_destroy(nsgtk_scaffolding *gs) -{ - LOG(("scaffold: %p", gs)); - - if (gtk_widget_in_destruction(GTK_WIDGET(gs->window)) != TRUE) { - gtk_widget_destroy(GTK_WIDGET(gs->window)); - } -} - /** * Update the back and forward button sensitivity. */ -static void nsgtk_window_update_back_forward(struct gtk_scaffolding *g) +static void nsgtk_window_update_back_forward(struct nsgtk_scaffolding *g) { int width, height; struct browser_window *bw = nsgtk_get_browser_window(g->top_level); g->buttons[BACK_BUTTON]->sensitivity = - history_back_available(bw->history); - g->buttons[FORWARD_BUTTON]->sensitivity = history_forward_available( - bw->history); + browser_window_history_back_available(bw); + g->buttons[FORWARD_BUTTON]->sensitivity = + browser_window_history_forward_available(bw); nsgtk_scaffolding_set_sensitivity(g); /* update the url bar, particularly necessary when tabbing */ - if (bw->current_content != NULL && - hlcache_handle_get_url(bw->current_content) != NULL) - browser_window_refresh_url_bar(bw, - hlcache_handle_get_url(bw->current_content), - bw->frag_id); + browser_window_refresh_url_bar(bw); /* update the local history window, as well as queuing a redraw * for it. */ - history_size(bw->history, &width, &height); + browser_window_history_size(bw, &width, &height); gtk_widget_set_size_request(GTK_WIDGET(g->history_window->drawing_area), width, height); gtk_widget_queue_draw(GTK_WIDGET(g->history_window->drawing_area)); @@ -336,7 +297,7 @@ static void nsgtk_window_update_back_forward(struct gtk_scaffolding *g) */ static void nsgtk_throb(void *p) { - struct gtk_scaffolding *g = p; + struct nsgtk_scaffolding *g = p; if (g->throb_frame >= (nsgtk_throbber->nframes - 1)) g->throb_frame = 1; @@ -346,11 +307,11 @@ static void nsgtk_throb(void *p) gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[ g->throb_frame]); - schedule(10, nsgtk_throb, p); + nsgtk_schedule(100, nsgtk_throb, p); } static guint nsgtk_scaffolding_update_edit_actions_sensitivity( - struct gtk_scaffolding *g) + struct nsgtk_scaffolding *g) { GtkWidget *widget = gtk_window_get_focus(g->window); gboolean has_selection; @@ -382,20 +343,9 @@ static guint nsgtk_scaffolding_update_edit_actions_sensitivity( (g->buttons[PASTE_BUTTON]->sensitivity)); } -static void nsgtk_scaffolding_enable_link_operations_sensitivity( - struct gtk_scaffolding *g) -{ - - gtk_widget_set_sensitive(GTK_WIDGET(g->menu_popup->savelink_menuitem), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(g->menu_popup->opentab_menuitem), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(g->menu_popup->openwin_menuitem), TRUE); - - popup_menu_show(g->menu_popup, false, true, false, false, false); - -} static void nsgtk_scaffolding_enable_edit_actions_sensitivity( - struct gtk_scaffolding *g) + struct nsgtk_scaffolding *g) { g->buttons[PASTE_BUTTON]->sensitivity = true; @@ -403,12 +353,12 @@ static void nsgtk_scaffolding_enable_edit_actions_sensitivity( g->buttons[CUT_BUTTON]->sensitivity = true; nsgtk_scaffolding_set_sensitivity(g); - popup_menu_show(g->menu_popup, false, false, false, true, false); + popup_menu_show(g->menu_popup, false, false, true, false); } /* signal handling functions for the toolbar, URL bar, and menu bar */ static gboolean nsgtk_window_edit_menu_clicked(GtkWidget *widget, - struct gtk_scaffolding *g) + struct nsgtk_scaffolding *g) { nsgtk_scaffolding_update_edit_actions_sensitivity(g); @@ -416,7 +366,7 @@ static gboolean nsgtk_window_edit_menu_clicked(GtkWidget *widget, } static gboolean nsgtk_window_edit_menu_hidden(GtkWidget *widget, - struct gtk_scaffolding *g) + struct nsgtk_scaffolding *g) { nsgtk_scaffolding_enable_edit_actions_sensitivity(g); @@ -424,44 +374,29 @@ static gboolean nsgtk_window_edit_menu_hidden(GtkWidget *widget, } static gboolean nsgtk_window_popup_menu_hidden(GtkWidget *widget, - struct gtk_scaffolding *g) + struct nsgtk_scaffolding *g) { - nsgtk_scaffolding_enable_link_operations_sensitivity(g); nsgtk_scaffolding_enable_edit_actions_sensitivity(g); return TRUE; } gboolean nsgtk_window_url_activate_event(GtkWidget *widget, gpointer data) { - struct gtk_scaffolding *g = data; - struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - char *urltxt; + struct nsgtk_scaffolding *g = data; + nserror ret; nsurl *url; - nserror error; - if (search_is_url(gtk_entry_get_text(GTK_ENTRY(g->url_bar))) == false) { - urltxt = search_web_from_term(gtk_entry_get_text(GTK_ENTRY( - g->url_bar))); - } else { - urltxt = strdup(gtk_entry_get_text(GTK_ENTRY(g->url_bar))); + ret = search_web_omni(gtk_entry_get_text(GTK_ENTRY(g->url_bar)), + SEARCH_WEB_OMNI_NONE, + &url); + if (ret == NSERROR_OK) { + ret = browser_window_navigate(nsgtk_get_browser_window(g->top_level), + url, NULL, BW_NAVIGATE_HISTORY, + NULL, NULL, NULL); + nsurl_unref(url); } - - if (urltxt != NULL) { - error = nsurl_create(urltxt, &url); - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } else { - browser_window_navigate(bw, - url, - NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - free(urltxt); + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); } return TRUE; @@ -485,11 +420,11 @@ gboolean nsgtk_window_url_changed(GtkWidget *widget, GdkEventKey *event, static gboolean nsgtk_window_tool_bar_clicked(GtkToolbar *toolbar, gint x, gint y, gint button, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; /* set visibility for right-click popup menu */ - popup_menu_hide(g->menu_popup, true, true, false, true, false); - popup_menu_show(g->menu_popup, false, false, false, false, true); + popup_menu_hide(g->menu_popup, true, false, true, false); + popup_menu_show(g->menu_popup, false, false, false, true); gtk_menu_popup(g->menu_popup->popup_menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time()); @@ -501,7 +436,7 @@ static gboolean nsgtk_window_tool_bar_clicked(GtkToolbar *toolbar, * Update the menus when the number of tabs changes. */ static void nsgtk_window_tabs_add(GtkNotebook *notebook, - GtkWidget *page, guint page_num, struct gtk_scaffolding *g) + GtkWidget *page, guint page_num, struct nsgtk_scaffolding *g) { gboolean visible = gtk_notebook_get_show_tabs(g->notebook); g_object_set(g->menu_bar->view_submenu->tabs_menuitem, "visible", visible, NULL); @@ -519,7 +454,7 @@ static void nsgtk_window_tabs_remove(GtkNotebook *notebook, GtkWidget *page, guint page_num, - struct gtk_scaffolding *gs) + struct nsgtk_scaffolding *gs) { /* if the scaffold is being destroyed it is not useful to * update the state, futher many of the widgets may have @@ -529,8 +464,9 @@ nsgtk_window_tabs_remove(GtkNotebook *notebook, return; } + /* if this is the last tab destroy the scaffold in addition */ if (gtk_notebook_get_n_pages(notebook) == 1) { - nsgtk_scaffolding_destroy(gs); + gtk_widget_destroy(GTK_WIDGET(gs->window)); return; } @@ -553,7 +489,7 @@ static void nsgtk_openfile_open(const char *filename) nsurl *url; nserror error; - bw = nsgtk_get_browser_window(current_model->top_level); + bw = nsgtk_get_browser_window(scaf_current->top_level); urltxt = malloc(strlen(filename) + FILE_SCHEME_PREFIX_LEN + 1); @@ -567,8 +503,7 @@ static void nsgtk_openfile_open(const char *filename) browser_window_navigate(bw, url, NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, + BW_NAVIGATE_HISTORY, NULL, NULL, NULL); @@ -595,7 +530,7 @@ MULTIHANDLER(newwindow) error = nsurl_create(addr, &url); if (error == NSERROR_OK) { - error = browser_window_create(BROWSER_WINDOW_VERIFIABLE, + error = browser_window_create(BW_CREATE_HISTORY, url, NULL, bw, @@ -628,8 +563,8 @@ nserror nsgtk_scaffolding_new_tab(struct gui_window *gw) } } - error = browser_window_create(BROWSER_WINDOW_VERIFIABLE | - BROWSER_WINDOW_TAB, + error = browser_window_create(BW_CREATE_HISTORY | + BW_CREATE_TAB, url, NULL, bw, @@ -653,9 +588,9 @@ MULTIHANDLER(newtab) MULTIHANDLER(openfile) { - current_model = g; + scaf_current = g; GtkWidget *dlgOpen = gtk_file_chooser_dialog_new("Open File", - current_model->window, GTK_FILE_CHOOSER_ACTION_OPEN, + scaf_current->window, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, -6, GTK_STOCK_OPEN, -5, NULL); gint response = gtk_dialog_run(GTK_DIALOG(dlgOpen)); @@ -684,8 +619,7 @@ static gboolean nsgtk_filter_directory(const GtkFileFilterInfo *info, MULTIHANDLER(savepage) { - if (nsgtk_get_browser_window(g->top_level)->current_content - == NULL) + if (!browser_window_has_content(nsgtk_get_browser_window(g->top_level))) return FALSE; GtkWidget *fc = gtk_file_chooser_dialog_new( @@ -696,7 +630,7 @@ MULTIHANDLER(savepage) NULL); DIR *d; char *path; - url_func_result res; + nserror res; GtkFileFilter *filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, "Directories"); gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME, @@ -704,9 +638,9 @@ MULTIHANDLER(savepage) gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fc), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fc), filter); - res = url_nice(nsurl_access(hlcache_handle_get_url(nsgtk_get_browser_window( - g->top_level)->current_content)), &path, false); - if (res != URL_FUNC_OK) { + res = url_nice(nsurl_access(browser_window_get_url( + nsgtk_get_browser_window(g->top_level))), &path, false); + if (res != NSERROR_OK) { path = strdup(messages_get("SaveText")); if (path == NULL) { warn_user("NoMemory", 0); @@ -740,8 +674,8 @@ MULTIHANDLER(savepage) return TRUE; } closedir(d); - save_complete(nsgtk_get_browser_window( - g->top_level)->current_content, path, NULL); + save_complete(browser_window_get_content(nsgtk_get_browser_window( + g->top_level)), path, NULL); g_free(path); gtk_widget_destroy(fc); @@ -760,15 +694,14 @@ MULTIHANDLER(pdf) char filename[PATH_MAX]; char dirname[PATH_MAX]; char *url_name; - url_func_result res; + nserror res; LOG(("Print preview (generating PDF) started.")); - res = url_nice(nsurl_access(hlcache_handle_get_url(bw->current_content)), + res = url_nice(nsurl_access(browser_window_get_url(bw)), &url_name, true); - if (res != URL_FUNC_OK) { - warn_user(messages_get(res == URL_FUNC_NOMEM ? "NoMemory" - : "URIError"), 0); + if (res != NSERROR_OK) { + warn_user(messages_get_errorcode(res), 0); return TRUE; } @@ -814,7 +747,8 @@ MULTIHANDLER(pdf) } /* This will clean up the print_settings object for us */ - print_basic_run(bw->current_content, &pdf_printer, settings); + print_basic_run(browser_window_get_content(bw), + &pdf_printer, settings); } gtk_widget_destroy(save_dialog); @@ -826,8 +760,7 @@ MULTIHANDLER(pdf) MULTIHANDLER(plaintext) { - if (nsgtk_get_browser_window(g->top_level)->current_content - == NULL) + if (!browser_window_has_content(nsgtk_get_browser_window(g->top_level))) return FALSE; GtkWidget *fc = gtk_file_chooser_dialog_new( @@ -837,11 +770,12 @@ MULTIHANDLER(plaintext) GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); char *filename; - url_func_result res; + nserror res; - res = url_nice(nsurl_access(hlcache_handle_get_url(nsgtk_get_browser_window( - g->top_level)->current_content)), &filename, false); - if (res != URL_FUNC_OK) { + res = url_nice(nsurl_access(browser_window_get_url( + nsgtk_get_browser_window(g->top_level))), + &filename, false); + if (res != NSERROR_OK) { filename = strdup(messages_get("SaveText")); if (filename == NULL) { warn_user("NoMemory", 0); @@ -857,8 +791,9 @@ MULTIHANDLER(plaintext) if (gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc)); - save_as_text(nsgtk_get_browser_window( - g->top_level)->current_content, filename); + save_as_text(browser_window_get_content( + nsgtk_get_browser_window( + g->top_level)), filename); g_free(filename); } @@ -888,9 +823,10 @@ MULTIHANDLER(print) GtkPrintOperation *print_op; GtkPageSetup *page_setup; - GtkPrintSettings *gtk_print_settings; + GtkPrintSettings *print_settings; GtkPrintOperationResult res = GTK_PRINT_OPERATION_RESULT_ERROR; - struct print_settings *settings; + struct print_settings *nssettings; + char *settings_fname = NULL; print_op = gtk_print_operation_new(); if (print_op == NULL) { @@ -899,48 +835,58 @@ MULTIHANDLER(print) } /* use previously saved settings if any */ - gtk_print_settings = gtk_print_settings_new_from_file( - print_options_file_location, NULL); - if (gtk_print_settings != NULL) { - gtk_print_operation_set_print_settings(print_op, - gtk_print_settings); - - /* We're not interested in the settings any more */ - g_object_unref(gtk_print_settings); + netsurf_mkpath(&settings_fname, NULL, 2, nsgtk_config_home, "Print"); + if (settings_fname != NULL) { + print_settings = gtk_print_settings_new_from_file(settings_fname, NULL); + if (print_settings != NULL) { + gtk_print_operation_set_print_settings(print_op, + print_settings); + + /* We're not interested in the settings any more */ + g_object_unref(print_settings); + } } - content_to_print = bw->current_content; + content_to_print = browser_window_get_content(bw); page_setup = gtk_print_run_page_setup_dialog(g->window, NULL, NULL); if (page_setup == NULL) { warn_user(messages_get("NoMemory"), 0); + free(settings_fname); g_object_unref(print_op); return TRUE; } gtk_print_operation_set_default_page_setup(print_op, page_setup); - settings = print_make_settings(PRINT_DEFAULT, NULL, &nsfont); + nssettings = print_make_settings(PRINT_DEFAULT, NULL, &nsfont); g_signal_connect(print_op, "begin_print", - G_CALLBACK(gtk_print_signal_begin_print), settings); + G_CALLBACK(gtk_print_signal_begin_print), nssettings); g_signal_connect(print_op, "draw_page", G_CALLBACK(gtk_print_signal_draw_page), NULL); g_signal_connect(print_op, "end_print", - G_CALLBACK(gtk_print_signal_end_print), settings); - if (content_get_type(bw->current_content) != CONTENT_TEXTPLAIN) + G_CALLBACK(gtk_print_signal_end_print), nssettings); + + if (content_get_type(browser_window_get_content(bw)) != + CONTENT_TEXTPLAIN) { res = gtk_print_operation_run(print_op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, g->window, NULL); + } /* if the settings were used save them for future use */ - if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { - /* Don't ref the settings, as we don't want to own them */ - gtk_print_settings = gtk_print_operation_get_print_settings( - print_op); - - gtk_print_settings_to_file(gtk_print_settings, - print_options_file_location, NULL); + if (settings_fname != NULL) { + if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { + /* Do not increment the settings reference */ + print_settings = + gtk_print_operation_get_print_settings(print_op); + + gtk_print_settings_to_file(print_settings, + settings_fname, + NULL); + } + free(settings_fname); } /* Our print_settings object is destroyed by the end print handler */ @@ -958,15 +904,23 @@ MULTIHANDLER(closewindow) MULTIHANDLER(quit) { - if (nsgtk_check_for_downloads(g->window) == false) - netsurf_quit = true; + struct nsgtk_scaffolding *gs; + + if (nsgtk_check_for_downloads(g->window) == false) { + gs = scaf_list; + while (gs != NULL) { + gtk_widget_destroy(GTK_WIDGET(gs->window)); + gs = gs->next; + } + } + return TRUE; } MENUHANDLER(savelink) { nsurl *url; - struct gtk_scaffolding *g = (struct gtk_scaffolding *) data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *) data; struct gui_window *gui = g->top_level; struct browser_window *bw = nsgtk_get_browser_window(gui); @@ -977,8 +931,7 @@ MENUHANDLER(savelink) browser_window_navigate(bw, url, NULL, - BROWSER_WINDOW_DOWNLOAD | - BROWSER_WINDOW_VERIFIABLE, + BW_NAVIGATE_DOWNLOAD, NULL, NULL, NULL); @@ -993,7 +946,7 @@ MENUHANDLER(savelink) */ MENUHANDLER(link_openwin) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *) data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *) data; struct gui_window *gui = g->top_level; struct browser_window *bw = nsgtk_get_browser_window(gui); nsurl *url; @@ -1004,12 +957,9 @@ MENUHANDLER(link_openwin) error = nsurl_create(current_menu_ctx.link_url, &url); if (error == NSERROR_OK) { - error = browser_window_create(BROWSER_WINDOW_VERIFIABLE | - BROWSER_WINDOW_HISTORY, - url, - NULL, - bw, - NULL); + error = browser_window_create( + BW_CREATE_CLONE | BW_CREATE_HISTORY, + url, NULL, bw, NULL); nsurl_unref(url); } if (error != NSERROR_OK) { @@ -1024,7 +974,7 @@ MENUHANDLER(link_openwin) */ MENUHANDLER(link_opentab) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *) data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *) data; struct gui_window *gui = g->top_level; struct browser_window *bw = nsgtk_get_browser_window(gui); nsurl *url; @@ -1037,13 +987,9 @@ MENUHANDLER(link_opentab) error = nsurl_create(current_menu_ctx.link_url, &url); if (error == NSERROR_OK) { - error = browser_window_create(BROWSER_WINDOW_VERIFIABLE | - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_TAB, - url, - NULL, - bw, - NULL); + error = browser_window_create(BW_CREATE_CLONE | + BW_CREATE_HISTORY | BW_CREATE_TAB, + url, NULL, bw, NULL); nsurl_unref(url); } if (error != NSERROR_OK) { @@ -1055,6 +1001,44 @@ MENUHANDLER(link_opentab) return TRUE; } +/** + * Handler for bookmarking a link. attached to the popup menu. + */ +MENUHANDLER(link_bookmark) +{ + nsurl *url; + nserror error; + + if (current_menu_ctx.link_url == NULL) + return FALSE; + + error = nsurl_create(current_menu_ctx.link_url, &url); + if (error == NSERROR_OK) { + hotlist_add_url(url); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } + + return TRUE; +} + +/** + * Handler for copying a link. attached to the popup menu. + */ +MENUHANDLER(link_copy) +{ + GtkClipboard *clipboard; + + if (current_menu_ctx.link_url == NULL) + return FALSE; + + clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, current_menu_ctx.link_url, -1); + return TRUE; +} + MULTIHANDLER(cut) { @@ -1105,7 +1089,7 @@ MULTIHANDLER(delete) MENUHANDLER(customize) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; nsgtk_toolbar_customization_init(g); return TRUE; } @@ -1188,15 +1172,14 @@ 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; } MENUHANDLER(menubar) { GtkWidget *w; - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; /* if the menubar is not being shown the popup menu shows the * menubar entries instead. @@ -1218,8 +1201,8 @@ MENUHANDLER(menubar) gtk_widget_show(GTK_WIDGET(g->menu_bar->bar_menu)); - popup_menu_show(g->menu_popup, false, true, true, true, true); - popup_menu_hide(g->menu_popup, true, false, false, false, false); + popup_menu_show(g->menu_popup, false, true, true, true); + popup_menu_hide(g->menu_popup, true, false, false, false); } else { w = GTK_WIDGET(g->menu_popup->view_submenu->toolbars_submenu->menubar_menuitem); if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))) @@ -1233,7 +1216,7 @@ MENUHANDLER(menubar) gtk_widget_hide(GTK_WIDGET(g->menu_bar->bar_menu)); - popup_menu_show(g->menu_popup, true, true, true, true, true); + popup_menu_show(g->menu_popup, true, true, true, true); } return TRUE; @@ -1242,7 +1225,7 @@ MENUHANDLER(menubar) MENUHANDLER(toolbar) { GtkWidget *w; - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { w = GTK_WIDGET(g->menu_popup->view_submenu->toolbars_submenu->toolbar_menuitem); @@ -1282,6 +1265,7 @@ MULTIHANDLER(downloads) MULTIHANDLER(savewindowsize) { int x,y,w,h; + char *choices = NULL; gtk_window_get_position(g->window, &x, &y); gtk_window_get_size(g->window, &w, &h); @@ -1291,7 +1275,11 @@ MULTIHANDLER(savewindowsize) nsoption_set_int(window_x, x); nsoption_set_int(window_y, y); - nsoption_write(options_file_location, NULL, NULL); + netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); + if (choices != NULL) { + nsoption_write(choices, NULL, NULL); + free(choices); + } return TRUE; } @@ -1303,96 +1291,72 @@ MULTIHANDLER(toggledebugging) return TRUE; } -MULTIHANDLER(saveboxtree) +MULTIHANDLER(debugboxtree) { - GtkWidget *save_dialog; - - save_dialog = gtk_file_chooser_dialog_new("Save File", g->window, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog), - getenv("HOME") ? getenv("HOME") : "/"); - - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog), - "boxtree.txt"); + gchar *fname; + gint handle; + FILE *f; + struct browser_window *bw; - if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) { - gchar *filename = gtk_file_chooser_get_filename( - GTK_FILE_CHOOSER(save_dialog)); - FILE *fh; + handle = g_file_open_tmp("nsgtkboxtreeXXXXXX", &fname, NULL); + if ((handle == -1) || (fname == NULL)) { + return TRUE; + } + close(handle); /* in case it was binary mode */ - LOG(("Saving box tree dump to %s...\n", filename)); + /* save data to temporary file */ + f = fopen(fname, "w"); + if (f == NULL) { + warn_user("Error saving box tree dump.", + "Unable to open file for writing."); + unlink(fname); + return TRUE; + } - fh = fopen((const char *) filename, "w"); - if (fh == NULL) { - warn_user("Error saving box tree dump.", - "Unable to open file for writing."); - } else { - struct browser_window *bw; - bw = nsgtk_get_browser_window(g->top_level); + bw = nsgtk_get_browser_window(g->top_level); - browser_window_debug_dump(bw, fh); + browser_window_debug_dump(bw, f, CONTENT_DEBUG_RENDER); - fclose(fh); - } + fclose(f); - g_free(filename); - } + nsgtk_viewfile("Box Tree Debug", "boxtree", fname); - gtk_widget_destroy(save_dialog); + g_free(fname); return TRUE; } -MULTIHANDLER(savedomtree) +MULTIHANDLER(debugdomtree) { - GtkWidget *save_dialog; - - save_dialog = gtk_file_chooser_dialog_new("Save File", g->window, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); + gchar *fname; + gint handle; + FILE *f; + struct browser_window *bw; - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog), - getenv("HOME") ? getenv("HOME") : "/"); + handle = g_file_open_tmp("nsgtkdomtreeXXXXXX", &fname, NULL); + if ((handle == -1) || (fname == NULL)) { + return TRUE; + } + close(handle); /* in case it was binary mode */ - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog), - "domtree.txt"); + /* save data to temporary file */ + f = fopen(fname, "w"); + if (f == NULL) { + warn_user("Error saving box tree dump.", + "Unable to open file for writing."); + unlink(fname); + return TRUE; + } - if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) { - gchar *filename = gtk_file_chooser_get_filename( - GTK_FILE_CHOOSER(save_dialog)); - FILE *fh; - LOG(("Saving dom tree to %s...\n", filename)); + bw = nsgtk_get_browser_window(g->top_level); - fh = fopen((const char *) filename, "w"); - if (fh == NULL) { - warn_user("Error saving box tree dump.", - "Unable to open file for writing."); - } else { - struct browser_window *bw; - bw = nsgtk_get_browser_window(g->top_level); - - if (bw->current_content && - content_get_type(bw->current_content) == - CONTENT_HTML) { -#ifdef FIXME - xmlDebugDumpDocument(fh, - html_get_document(bw->current_content)); -#endif - } + browser_window_debug_dump(bw, f, CONTENT_DEBUG_DOM); - fclose(fh); - } + fclose(f); - g_free(filename); - } + nsgtk_viewfile("DOM Tree Debug", "domtree", fname); - gtk_widget_destroy(save_dialog); + g_free(fname); return TRUE; } @@ -1418,9 +1382,6 @@ MULTIHANDLER(reload) /* clear potential search effects */ browser_window_search_clear(bw); - nsgtk_search_set_forward_state(true, bw); - nsgtk_search_set_back_state(true, bw); - browser_window_reload(bw, true); return TRUE; @@ -1431,16 +1392,13 @@ MULTIHANDLER(back) struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - if ((bw == NULL) || (!history_back_available(bw->history))) + if ((bw == NULL) || (!browser_window_history_back_available(bw))) return TRUE; /* clear potential search effects */ browser_window_search_clear(bw); - nsgtk_search_set_forward_state(true, bw); - nsgtk_search_set_back_state(true, bw); - - history_back(bw, bw->history); + browser_window_history_back(bw, false); nsgtk_window_update_back_forward(g); return TRUE; @@ -1451,16 +1409,13 @@ MULTIHANDLER(forward) struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - if ((bw == NULL) || (!history_forward_available(bw->history))) + if ((bw == NULL) || (!browser_window_history_forward_available(bw))) return TRUE; /* clear potential search effects */ browser_window_search_clear(bw); - nsgtk_search_set_forward_state(true, bw); - nsgtk_search_set_back_state(true, bw); - - history_forward(bw, bw->history); + browser_window_history_forward(bw, false); nsgtk_window_update_back_forward(g); return TRUE; @@ -1484,8 +1439,7 @@ MULTIHANDLER(home) browser_window_navigate(bw, url, NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, + BW_NAVIGATE_HISTORY, NULL, NULL, NULL); @@ -1503,7 +1457,7 @@ MULTIHANDLER(localhistory) /* if entries of the same url but different frag_ids have been added * the history needs redrawing (what throbber code normally does) */ - history_size(bw->history, &width, &height); + browser_window_history_size(bw, &width, &height); nsgtk_window_update_back_forward(g); gtk_window_get_position(g->window, &x, &y); gtk_window_get_size(g->window, &mainwidth, &mainheight); @@ -1537,10 +1491,9 @@ MULTIHANDLER(addbookmarks) { struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - if (bw == NULL || bw->current_content == NULL || - hlcache_handle_get_url(bw->current_content) == NULL) + if (bw == NULL || !browser_window_has_content(bw)) return TRUE; - hotlist_add_url(hlcache_handle_get_url(bw->current_content)); + hotlist_add_url(browser_window_get_url(bw)); return TRUE; } @@ -1602,8 +1555,7 @@ MULTIHANDLER(contents) browser_window_navigate(bw, url, NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, + BW_NAVIGATE_HISTORY, NULL, NULL, NULL); @@ -1624,8 +1576,7 @@ MULTIHANDLER(guide) browser_window_navigate(bw, url, NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, + BW_NAVIGATE_HISTORY, NULL, NULL, NULL); @@ -1646,8 +1597,7 @@ MULTIHANDLER(info) browser_window_navigate(bw, url, NULL, - BROWSER_WINDOW_HISTORY | - BROWSER_WINDOW_VERIFIABLE, + BW_NAVIGATE_HISTORY, NULL, NULL, NULL); @@ -1659,15 +1609,13 @@ MULTIHANDLER(info) MULTIHANDLER(about) { - nsgtk_about_dialog_init(g->window, - nsgtk_get_browser_window(g->top_level), - netsurf_version); + nsgtk_about_dialog_init(g->window, netsurf_version); return TRUE; } BUTTONHANDLER(history) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; return nsgtk_on_localhistory_activate(g); } @@ -1707,7 +1655,7 @@ nsgtk_history_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data) ctx.plot->clip(&clip); - history_redraw(bw->history, &ctx); + browser_window_history_redraw(bw, &ctx); current_widget = NULL; @@ -1740,7 +1688,7 @@ nsgtk_history_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer g) clip.y1 = event->area.y + event->area.height; ctx.plot->clip(&clip); - history_redraw(bw->history, &ctx); + browser_window_history_redraw(bw, &ctx); cairo_destroy(current_cr); @@ -1760,15 +1708,14 @@ static gboolean nsgtk_history_button_press_event(GtkWidget *widget, LOG(("X=%g, Y=%g", event->x, event->y)); - history_click(bw, bw->history, - event->x, event->y, false); + browser_window_history_click(bw, event->x, event->y, false); return TRUE; } -static void nsgtk_attach_menu_handlers(struct gtk_scaffolding *g) +static void nsgtk_attach_menu_handlers(struct nsgtk_scaffolding *g) { for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { if (g->buttons[i]->main != NULL) { @@ -1797,25 +1744,58 @@ static void nsgtk_attach_menu_handlers(struct gtk_scaffolding *g) * Create and connect handlers to popup menu. * * \param g scaffoliding to attach popup menu to. - * \return true on success or false on error. + * \return menu structure on sucess or NULL on error. */ -static bool nsgtk_new_scaffolding_popup(struct gtk_scaffolding *g, GtkAccelGroup *group) +static struct nsgtk_popup_menu * +nsgtk_new_scaffolding_popup(struct nsgtk_scaffolding *g, GtkAccelGroup *group) { - struct nsgtk_popup_submenu *nmenu; + struct nsgtk_popup_menu *nmenu; - nmenu = nsgtk_menu_popup_create(group); + nmenu = nsgtk_popup_menu_create(group); - if (nmenu == NULL) - return false; + if (nmenu == NULL) { + return NULL; + } -/** Connect a GTK signal handler to a widget */ -#define SIG_CONNECT(obj, sig, callback, ptr) \ - g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + g_signal_connect(nmenu->popup_menu, "hide", + G_CALLBACK(nsgtk_window_popup_menu_hidden), g); - SIG_CONNECT(nmenu->popup_menu, "hide", - nsgtk_window_popup_menu_hidden, g); + g_signal_connect(nmenu->cut_menuitem, "activate", + G_CALLBACK(nsgtk_on_cut_activate_menu), g); + + g_signal_connect(nmenu->copy_menuitem, "activate", + G_CALLBACK(nsgtk_on_copy_activate_menu), g); + + g_signal_connect(nmenu->paste_menuitem, "activate", + G_CALLBACK(nsgtk_on_paste_activate_menu), g); + + g_signal_connect(nmenu->customize_menuitem, "activate", + G_CALLBACK(nsgtk_on_customize_activate_menu), g); - g_signal_connect(nmenu->savelink_menuitem, "activate", + /* set initial popup menu visibility */ + popup_menu_hide(nmenu, true, false, false, true); + + return nmenu; +} + +/** + * Create and connect handlers to link popup menu. + * + * \param g scaffoliding to attach popup menu to. + * \return true on success or false on error. + */ +static struct nsgtk_link_menu * +nsgtk_new_scaffolding_link_popup(struct nsgtk_scaffolding *g, GtkAccelGroup *group) +{ + struct nsgtk_link_menu *nmenu; + + nmenu = nsgtk_link_menu_create(group); + + if (nmenu == NULL) { + return NULL; + } + + g_signal_connect(nmenu->save_menuitem, "activate", G_CALLBACK(nsgtk_on_savelink_activate_menu), g); g_signal_connect(nmenu->opentab_menuitem, "activate", @@ -1824,30 +1804,182 @@ static bool nsgtk_new_scaffolding_popup(struct gtk_scaffolding *g, GtkAccelGroup g_signal_connect(nmenu->openwin_menuitem, "activate", G_CALLBACK(nsgtk_on_link_openwin_activate_menu), g); - g_signal_connect(nmenu->cut_menuitem, "activate", - G_CALLBACK(nsgtk_on_cut_activate_menu), g); + g_signal_connect(nmenu->bookmark_menuitem, "activate", + G_CALLBACK(nsgtk_on_link_bookmark_activate_menu), g); g_signal_connect(nmenu->copy_menuitem, "activate", - G_CALLBACK(nsgtk_on_copy_activate_menu), g); + G_CALLBACK(nsgtk_on_link_copy_activate_menu), g); - g_signal_connect(nmenu->paste_menuitem, "activate", - G_CALLBACK(nsgtk_on_paste_activate_menu), g); + return nmenu; +} - g_signal_connect(nmenu->customize_menuitem, "activate", - G_CALLBACK(nsgtk_on_customize_activate_menu), g); +/* exported interface documented in gtk/scaffolding.h */ +struct nsgtk_scaffolding *nsgtk_current_scaffolding(void) +{ + if (scaf_current == NULL) { + scaf_current = scaf_list; + } + return scaf_current; +} - /* set initial popup menu visibility */ - popup_menu_hide(nmenu, true, false, false, false, true); +/** + * init the array g->buttons[] + */ +static void nsgtk_scaffolding_toolbar_init(struct nsgtk_scaffolding *g) +{ +#define ITEM_MAIN(p, q, r)\ + g->buttons[p##_BUTTON]->main = g->menu_bar->q->r##_menuitem;\ + g->buttons[p##_BUTTON]->rclick = g->menu_popup->q->r##_menuitem;\ + g->buttons[p##_BUTTON]->mhandler = nsgtk_on_##r##_activate_menu;\ + g->buttons[p##_BUTTON]->bhandler = nsgtk_on_##r##_activate_button;\ + g->buttons[p##_BUTTON]->dataplus = nsgtk_toolbar_##r##_button_data;\ + g->buttons[p##_BUTTON]->dataminus = nsgtk_toolbar_##r##_toolbar_button_data + +#define ITEM_SUB(p, q, r, s)\ + g->buttons[p##_BUTTON]->main =\ + g->menu_bar->q->r##_submenu->s##_menuitem;\ + g->buttons[p##_BUTTON]->rclick =\ + g->menu_popup->q->r##_submenu->s##_menuitem;\ + g->buttons[p##_BUTTON]->mhandler =\ + nsgtk_on_##s##_activate_menu;\ + g->buttons[p##_BUTTON]->bhandler =\ + nsgtk_on_##s##_activate_button;\ + g->buttons[p##_BUTTON]->dataplus =\ + nsgtk_toolbar_##s##_button_data;\ + g->buttons[p##_BUTTON]->dataminus =\ + nsgtk_toolbar_##s##_toolbar_button_data + +#define ITEM_BUTTON(p, q)\ + g->buttons[p##_BUTTON]->bhandler =\ + nsgtk_on_##q##_activate;\ + g->buttons[p##_BUTTON]->dataplus =\ + nsgtk_toolbar_##q##_button_data;\ + g->buttons[p##_BUTTON]->dataminus =\ + nsgtk_toolbar_##q##_toolbar_button_data + +#define ITEM_POP(p, q) \ + g->buttons[p##_BUTTON]->popup = GTK_IMAGE_MENU_ITEM(\ + g->menu_popup->q##_menuitem) + +#define SENSITIVITY(q) \ + g->buttons[q##_BUTTON]->sensitivity = false - g->menu_popup = nmenu; +#define ITEM_ITEM(p, q)\ + g->buttons[p##_ITEM]->dataplus =\ + nsgtk_toolbar_##q##_button_data;\ + g->buttons[p##_ITEM]->dataminus =\ + nsgtk_toolbar_##q##_toolbar_button_data + + ITEM_ITEM(WEBSEARCH, websearch); + ITEM_ITEM(THROBBER, throbber); + ITEM_MAIN(NEWWINDOW, file_submenu, newwindow); + ITEM_MAIN(NEWTAB, file_submenu, newtab); + ITEM_MAIN(OPENFILE, file_submenu, openfile); + ITEM_MAIN(PRINT, file_submenu, print); + ITEM_MAIN(CLOSEWINDOW, file_submenu, closewindow); + ITEM_MAIN(SAVEPAGE, file_submenu, savepage); + ITEM_MAIN(PRINTPREVIEW, file_submenu, printpreview); + ITEM_MAIN(PRINT, file_submenu, print); + ITEM_MAIN(QUIT, file_submenu, quit); + ITEM_MAIN(CUT, edit_submenu, cut); + ITEM_MAIN(COPY, edit_submenu, copy); + ITEM_MAIN(PASTE, edit_submenu, paste); + ITEM_MAIN(DELETE, edit_submenu, delete); + ITEM_MAIN(SELECTALL, edit_submenu, selectall); + ITEM_MAIN(FIND, edit_submenu, find); + ITEM_MAIN(PREFERENCES, edit_submenu, preferences); + ITEM_MAIN(STOP, view_submenu, stop); + ITEM_POP(STOP, stop); + ITEM_MAIN(RELOAD, view_submenu, reload); + ITEM_POP(RELOAD, reload); + ITEM_MAIN(FULLSCREEN, view_submenu, fullscreen); + ITEM_MAIN(DOWNLOADS, tools_submenu, downloads); + ITEM_MAIN(SAVEWINDOWSIZE, view_submenu, savewindowsize); + ITEM_MAIN(BACK, nav_submenu, back); + ITEM_POP(BACK, back); + ITEM_MAIN(FORWARD, nav_submenu, forward); + ITEM_POP(FORWARD, forward); + ITEM_MAIN(HOME, nav_submenu, home); + ITEM_MAIN(LOCALHISTORY, nav_submenu, localhistory); + ITEM_MAIN(GLOBALHISTORY, nav_submenu, globalhistory); + ITEM_MAIN(ADDBOOKMARKS, nav_submenu, addbookmarks); + ITEM_MAIN(SHOWBOOKMARKS, nav_submenu, showbookmarks); + ITEM_MAIN(SHOWCOOKIES, tools_submenu, showcookies); + ITEM_MAIN(OPENLOCATION, nav_submenu, openlocation); + ITEM_MAIN(CONTENTS, help_submenu, contents); + ITEM_MAIN(INFO, help_submenu, info); + ITEM_MAIN(GUIDE, help_submenu, guide); + ITEM_MAIN(ABOUT, help_submenu, about); + ITEM_SUB(PLAINTEXT, file_submenu, export, plaintext); + ITEM_SUB(PDF, file_submenu, export, pdf); + ITEM_SUB(DRAWFILE, file_submenu, export, drawfile); + ITEM_SUB(POSTSCRIPT, file_submenu, export, postscript); + ITEM_SUB(ZOOMPLUS, view_submenu, scaleview, zoomplus); + ITEM_SUB(ZOOMMINUS, view_submenu, scaleview, zoomminus); + ITEM_SUB(ZOOMNORMAL, view_submenu, scaleview, zoomnormal); + ITEM_SUB(NEXTTAB, view_submenu, tabs, nexttab); + ITEM_SUB(PREVTAB, view_submenu, tabs, prevtab); + ITEM_SUB(CLOSETAB, view_submenu, tabs, closetab); + + /* development submenu */ + ITEM_SUB(VIEWSOURCE, tools_submenu, developer, viewsource); + ITEM_SUB(TOGGLEDEBUGGING, tools_submenu, developer, toggledebugging); + ITEM_SUB(SAVEBOXTREE, tools_submenu, developer, debugboxtree); + ITEM_SUB(SAVEDOMTREE, tools_submenu, developer, debugdomtree); + ITEM_BUTTON(HISTORY, history); + + /* disable items that make no sense initially, as well as + * as-yet-unimplemented items */ + SENSITIVITY(BACK); + SENSITIVITY(FORWARD); + SENSITIVITY(STOP); + SENSITIVITY(PRINTPREVIEW); + SENSITIVITY(DELETE); + SENSITIVITY(DRAWFILE); + SENSITIVITY(POSTSCRIPT); + SENSITIVITY(NEXTTAB); + SENSITIVITY(PREVTAB); + SENSITIVITY(CLOSETAB); +#ifndef WITH_PDF_EXPORT + SENSITIVITY(PDF); +#endif + +#undef ITEM_MAIN +#undef ITEM_SUB +#undef ITEM_BUTTON +#undef ITEM_POP +#undef SENSITIVITY - return true; } -nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) +static void nsgtk_scaffolding_initial_sensitivity(struct nsgtk_scaffolding *g) { - struct gtk_scaffolding *g; - char *searchname; + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + if (g->buttons[i]->main != NULL) + gtk_widget_set_sensitive(GTK_WIDGET( + g->buttons[i]->main), + g->buttons[i]->sensitivity); + if (g->buttons[i]->rclick != NULL) + gtk_widget_set_sensitive(GTK_WIDGET( + g->buttons[i]->rclick), + g->buttons[i]->sensitivity); + if ((g->buttons[i]->location != -1) && + (g->buttons[i]->button != NULL)) + gtk_widget_set_sensitive(GTK_WIDGET( + g->buttons[i]->button), + g->buttons[i]->sensitivity); + if (g->buttons[i]->popup != NULL) + gtk_widget_set_sensitive(GTK_WIDGET( + g->buttons[i]->popup), + g->buttons[i]->sensitivity); + } + gtk_widget_set_sensitive(GTK_WIDGET(g->menu_bar->view_submenu->images_menuitem), FALSE); +} + +/* exported interface documented in gtk/scaffolding.h */ +struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) +{ + struct nsgtk_scaffolding *g; int i; GtkAccelGroup *group; GError* error = NULL; @@ -2104,37 +2236,19 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) nsgtk_window_tool_bar_clicked, g); /* create popup menu */ - nsgtk_new_scaffolding_popup(g, group); + g->menu_popup = nsgtk_new_scaffolding_popup(g, group); + + g->link_menu = nsgtk_new_scaffolding_link_popup(g, group); /* set up the menu signal handlers */ nsgtk_scaffolding_toolbar_init(g); nsgtk_toolbar_connect_all(g); nsgtk_attach_menu_handlers(g); - /* prepare to set the web search ico */ - - /* init web search prefs from file */ - search_web_provider_details(nsoption_int(search_provider)); - - /* potentially retrieve ico */ - if (search_web_ico() == NULL) { - search_web_retrieve_ico(false); - } - - /* set entry */ - searchname = search_web_provider_name(); - if (searchname != NULL) { - char searchcontent[strlen(searchname) + SLEN("Search ") + 1]; - sprintf(searchcontent, "Search %s", searchname); - nsgtk_scaffolding_set_websearch(g, searchcontent); - free(searchname); - } - nsgtk_scaffolding_initial_sensitivity(g); g->fullscreen = false; - /* attach to the list */ if (scaf_list) scaf_list->prev = g; @@ -2146,9 +2260,8 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) nsgtk_theme_init(); nsgtk_theme_implement(g); - /* set web search ico */ - if (search_web_ico() != NULL) - gui_window_set_search_ico(search_web_ico()); + /* set web search provider */ + search_web_select_provider(nsoption_int(search_provider)); /* finally, show the window. */ gtk_widget_show(GTK_WIDGET(g->window)); @@ -2165,7 +2278,7 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) */ void gui_window_set_title(struct gui_window *gw, const char *title) { - struct gtk_scaffolding *gs = nsgtk_get_scaffold(gw); + struct nsgtk_scaffolding *gs = nsgtk_get_scaffold(gw); int title_len; char *newtitle; @@ -2199,7 +2312,7 @@ void gui_window_set_title(struct gui_window *gw, const char *title) void gui_window_set_url(struct gui_window *_g, const char *url) { - struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); if (g->top_level != _g) return; gtk_entry_set_text(GTK_ENTRY(g->url_bar), url); gtk_editable_set_position(GTK_EDITABLE(g->url_bar), -1); @@ -2207,23 +2320,23 @@ void gui_window_set_url(struct gui_window *_g, const char *url) void gui_window_start_throbber(struct gui_window* _g) { - struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); g->buttons[STOP_BUTTON]->sensitivity = true; g->buttons[RELOAD_BUTTON]->sensitivity = false; nsgtk_scaffolding_set_sensitivity(g); nsgtk_window_update_back_forward(g); - schedule(10, nsgtk_throb, g); + nsgtk_schedule(100, nsgtk_throb, g); } void gui_window_stop_throbber(struct gui_window* _g) { - struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); if (g == NULL) return; nsgtk_window_update_back_forward(g); - schedule_remove(nsgtk_throb, g); + nsgtk_schedule(-1, nsgtk_throb, g); if (g->buttons[STOP_BUTTON] != NULL) g->buttons[STOP_BUTTON]->sensitivity = false; if (g->buttons[RELOAD_BUTTON] != NULL) @@ -2245,7 +2358,7 @@ void gui_window_stop_throbber(struct gui_window* _g) void nsgtk_scaffolding_set_icon(struct gui_window *gw) { - struct gtk_scaffolding *sc = nsgtk_get_scaffold(gw); + struct nsgtk_scaffolding *sc = nsgtk_get_scaffold(gw); GdkPixbuf *icon_pixbuf = nsgtk_get_icon(gw); /* check icon needs to be shown */ @@ -2261,103 +2374,200 @@ nsgtk_scaffolding_set_icon(struct gui_window *gw) gtk_widget_show_all(GTK_WIDGET(sc->buttons[URL_BAR_ITEM]->button)); } -void gui_window_set_search_ico(hlcache_handle *ico) +static void +nsgtk_scaffolding_set_websearch(struct nsgtk_scaffolding *g, const char *content) { - struct bitmap *srch_bitmap; - nsgtk_scaffolding *current; - GdkPixbuf *srch_pixbuf; + /** \todo this code appears technically correct, though + * currently has no effect at all. + */ + PangoLayout *lo = gtk_entry_get_layout(GTK_ENTRY(g->webSearchEntry)); + if (lo != NULL) { + pango_layout_set_font_description(lo, NULL); + PangoFontDescription *desc = pango_font_description_new(); + if (desc != NULL) { + pango_font_description_set_style(desc, + PANGO_STYLE_ITALIC); + pango_font_description_set_family(desc, "Arial"); + pango_font_description_set_weight(desc, + PANGO_WEIGHT_ULTRALIGHT); + pango_font_description_set_size(desc, + 10 * PANGO_SCALE); + pango_layout_set_font_description(lo, desc); + } - if ((ico == NULL) && - (ico = search_web_ico()) == NULL) { - return; + PangoAttrList *list = pango_attr_list_new(); + if (list != NULL) { + PangoAttribute *italic = pango_attr_style_new( + PANGO_STYLE_ITALIC); + if (italic != NULL) { + italic->start_index = 0; + italic->end_index = strlen(content); + } + PangoAttribute *grey = pango_attr_foreground_new( + 0x7777, 0x7777, 0x7777); + if (grey != NULL) { + grey->start_index = 0; + grey->end_index = strlen(content); + } + pango_attr_list_insert(list, italic); + pango_attr_list_insert(list, grey); + pango_layout_set_attributes(lo, list); + pango_attr_list_unref(list); + } + pango_layout_set_text(lo, content, -1); } +/* an alternative method */ +/* char *parse = malloc(strlen(content) + 1); + PangoAttrList *list = pango_layout_get_attributes(lo); + char *markup = g_strconcat("<span foreground='#777777'><i>", content, + "</i></span>", NULL); + pango_parse_markup(markup, -1, 0, &list, &parse, NULL, NULL); + gtk_widget_show_all(g->webSearchEntry); +*/ + gtk_entry_set_visibility(GTK_ENTRY(g->webSearchEntry), TRUE); + gtk_entry_set_text(GTK_ENTRY(g->webSearchEntry), content); +} - srch_bitmap = content_get_bitmap(ico); - if (srch_bitmap == NULL) { - return; - } +/** + * GTK UI callback when search provider details are updated. + * + * \param provider_name The providers name. + * \param ico_bitmap The icon bitmap representing the provider. + * \return NSERROR_OK on success else error code. + */ +static nserror +gui_search_web_provider_update(const char *provider_name, + struct bitmap *provider_bitmap) +{ + struct nsgtk_scaffolding *current; + GdkPixbuf *srch_pixbuf = NULL; + char *searchcontent; - srch_pixbuf = nsgdk_pixbuf_get_from_surface(srch_bitmap->surface, 16, 16); + LOG(("name:%s bitmap %p", provider_name, provider_bitmap)); - if (srch_pixbuf == NULL) { - return; + if (provider_bitmap != NULL) { + srch_pixbuf = nsgdk_pixbuf_get_from_surface(provider_bitmap->surface, 16, 16); + + if (srch_pixbuf == NULL) { + return NSERROR_NOMEM; + } } - /* add ico to each window's toolbar */ + /* setup the search content name */ + searchcontent = malloc(strlen(provider_name) + SLEN("Search ") + 1); + if (searchcontent != NULL) { + sprintf(searchcontent, "Search %s", provider_name); + } + + /* set the search provider parameters up in each scaffold */ for (current = scaf_list; current != NULL; current = current->next) { - nsgtk_entry_set_icon_from_pixbuf(current->webSearchEntry, - GTK_ENTRY_ICON_PRIMARY, - srch_pixbuf); + /* add ico to each window's toolbar */ + if (srch_pixbuf != NULL) { + nsgtk_entry_set_icon_from_pixbuf(current->webSearchEntry, + GTK_ENTRY_ICON_PRIMARY, + srch_pixbuf); + } else { + nsgtk_entry_set_icon_from_stock(current->webSearchEntry, + GTK_ENTRY_ICON_PRIMARY, + "gtk-find"); + } + + /* set search entry text */ + if (searchcontent != NULL) { + nsgtk_scaffolding_set_websearch(current, searchcontent); + } else { + nsgtk_scaffolding_set_websearch(current, provider_name); + } } - g_object_unref(srch_pixbuf); -} + free(searchcontent); -bool nsgtk_scaffolding_is_busy(nsgtk_scaffolding *g) -{ - /* We are considered "busy" if the stop button is sensitive */ - return g->buttons[STOP_BUTTON]->sensitivity; + if (srch_pixbuf != NULL) { + g_object_unref(srch_pixbuf); + } + + return NSERROR_OK; } -GtkWindow* nsgtk_scaffolding_window(nsgtk_scaffolding *g) +static struct gui_search_web_table search_web_table = { + .provider_update = gui_search_web_provider_update, +}; + +struct gui_search_web_table *nsgtk_search_web_table = &search_web_table; + +/* exported interface documented in gtk/scaffolding.h */ +GtkWindow* nsgtk_scaffolding_window(struct nsgtk_scaffolding *g) { return g->window; } -GtkNotebook* nsgtk_scaffolding_notebook(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +GtkNotebook* nsgtk_scaffolding_notebook(struct nsgtk_scaffolding *g) { return g->notebook; } -GtkWidget *nsgtk_scaffolding_urlbar(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +GtkWidget *nsgtk_scaffolding_urlbar(struct nsgtk_scaffolding *g) { return g->url_bar; } -GtkWidget *nsgtk_scaffolding_websearch(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +GtkWidget *nsgtk_scaffolding_websearch(struct nsgtk_scaffolding *g) { return g->webSearchEntry; } - -GtkToolbar *nsgtk_scaffolding_toolbar(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +GtkToolbar *nsgtk_scaffolding_toolbar(struct nsgtk_scaffolding *g) { return g->tool_bar; } -struct nsgtk_button_connect *nsgtk_scaffolding_button(nsgtk_scaffolding *g, - int i) +/* exported interface documented in gtk/scaffolding.h */ +struct nsgtk_button_connect * +nsgtk_scaffolding_button(struct nsgtk_scaffolding *g, int i) { return g->buttons[i]; } -struct gtk_search *nsgtk_scaffolding_search(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +struct gtk_search *nsgtk_scaffolding_search(struct nsgtk_scaffolding *g) { return g->search; } -GtkMenuBar *nsgtk_scaffolding_menu_bar(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +GtkMenuBar *nsgtk_scaffolding_menu_bar(struct nsgtk_scaffolding *g) { return g->menu_bar->bar_menu; } -struct gtk_history_window *nsgtk_scaffolding_history_window(nsgtk_scaffolding - *g) +/* exported interface documented in gtk/scaffolding.h */ +struct gtk_history_window * +nsgtk_scaffolding_history_window(struct nsgtk_scaffolding *g) { return g->history_window; } -nsgtk_scaffolding *nsgtk_scaffolding_iterate(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +struct nsgtk_scaffolding *nsgtk_scaffolding_iterate(struct nsgtk_scaffolding *g) { + if (g == NULL) { + return scaf_list; + } return g->next; } -void nsgtk_scaffolding_reset_offset(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_reset_offset(struct nsgtk_scaffolding *g) { g->offset = 0; } -void nsgtk_scaffolding_update_url_bar_ref(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_update_url_bar_ref(struct nsgtk_scaffolding *g) { g->url_bar = GTK_WIDGET(gtk_bin_get_child(GTK_BIN( nsgtk_scaffolding_button(g, URL_BAR_ITEM)->button))); @@ -2365,81 +2575,33 @@ void nsgtk_scaffolding_update_url_bar_ref(nsgtk_scaffolding *g) gtk_entry_set_completion(GTK_ENTRY(g->url_bar), g->url_bar_completion); } -void nsgtk_scaffolding_update_throbber_ref(nsgtk_scaffolding *g) + +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_update_throbber_ref(struct nsgtk_scaffolding *g) { g->throbber = GTK_IMAGE(gtk_bin_get_child(GTK_BIN(gtk_bin_get_child( GTK_BIN(g->buttons[THROBBER_ITEM]->button))))); } -void nsgtk_scaffolding_update_websearch_ref(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_update_websearch_ref(struct nsgtk_scaffolding *g) { g->webSearchEntry = gtk_bin_get_child(GTK_BIN( g->buttons[WEBSEARCH_ITEM]->button)); } -void nsgtk_scaffolding_set_websearch(nsgtk_scaffolding *g, const char *content) -{ - /* this code appears technically correct, though currently has no - * effect at all - tinkering encouraged */ - PangoLayout *lo = gtk_entry_get_layout(GTK_ENTRY(g->webSearchEntry)); - if (lo != NULL) { - pango_layout_set_font_description(lo, NULL); - PangoFontDescription *desc = pango_font_description_new(); - if (desc != NULL) { - pango_font_description_set_style(desc, - PANGO_STYLE_ITALIC); - pango_font_description_set_family(desc, "Arial"); - pango_font_description_set_weight(desc, - PANGO_WEIGHT_ULTRALIGHT); - pango_font_description_set_size(desc, - 10 * PANGO_SCALE); - pango_layout_set_font_description(lo, desc); - } - - PangoAttrList *list = pango_attr_list_new(); - if (list != NULL) { - PangoAttribute *italic = pango_attr_style_new( - PANGO_STYLE_ITALIC); - if (italic != NULL) { - italic->start_index = 0; - italic->end_index = strlen(content); - } - PangoAttribute *grey = pango_attr_foreground_new( - 0x7777, 0x7777, 0x7777); - if (grey != NULL) { - grey->start_index = 0; - grey->end_index = strlen(content); - } - pango_attr_list_insert(list, italic); - pango_attr_list_insert(list, grey); - pango_layout_set_attributes(lo, list); - pango_attr_list_unref(list); - } - pango_layout_set_text(lo, content, -1); - } -/* an alternative method */ -/* char *parse = malloc(strlen(content) + 1); - PangoAttrList *list = pango_layout_get_attributes(lo); - char *markup = g_strconcat("<span foreground='#777777'><i>", content, - "</i></span>", NULL); - pango_parse_markup(markup, -1, 0, &list, &parse, NULL, NULL); - gtk_widget_show_all(g->webSearchEntry); -*/ - gtk_entry_set_visibility(GTK_ENTRY(g->webSearchEntry), TRUE); - gtk_entry_set_text(GTK_ENTRY(g->webSearchEntry), content); -} - -void nsgtk_scaffolding_toggle_search_bar_visibility(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_toggle_search_bar_visibility(struct nsgtk_scaffolding *g) { gboolean vis; - struct browser_window *bw = - nsgtk_get_browser_window(g->top_level); + struct browser_window *bw = nsgtk_get_browser_window(g->top_level); + g_object_get(G_OBJECT(g->search->bar), "visible", &vis, NULL); if (vis) { - if (bw != NULL) + if (bw != NULL) { browser_window_search_clear(bw); - nsgtk_search_set_forward_state(true, bw); - nsgtk_search_set_back_state(true, bw); + } + gtk_widget_hide(GTK_WIDGET(g->search->bar)); } else { gtk_widget_show(GTK_WIDGET(g->search->bar)); @@ -2447,17 +2609,17 @@ void nsgtk_scaffolding_toggle_search_bar_visibility(nsgtk_scaffolding *g) } } - -struct gui_window *nsgtk_scaffolding_top_level(nsgtk_scaffolding *g) +/* exported interface documented in gtk/scaffolding.h */ +struct gui_window *nsgtk_scaffolding_top_level(struct nsgtk_scaffolding *g) { return g->top_level; } -/* set the current active top level gui window */ +/* exported interface documented in gtk/scaffolding.h */ void nsgtk_scaffolding_set_top_level(struct gui_window *gw) { struct browser_window *bw; - nsgtk_scaffolding *sc; + struct nsgtk_scaffolding *sc; assert(gw != NULL); @@ -2476,19 +2638,15 @@ void nsgtk_scaffolding_set_top_level(struct gui_window *gw) /* clear effects of potential searches */ browser_window_search_clear(bw); - nsgtk_search_set_forward_state(true, bw); - nsgtk_search_set_back_state(true, bw); - nsgtk_scaffolding_set_icon(gw); /* Ensure the window's title bar is updated */ - if (bw->current_content != NULL) { - gui_window_set_title(gw, content_get_title(bw->current_content)); - } + gui_window_set_title(gw, browser_window_get_title(bw)); + } /* exported interface documented in scaffolding.h */ -void nsgtk_scaffolding_set_sensitivity(struct gtk_scaffolding *g) +void nsgtk_scaffolding_set_sensitivity(struct nsgtk_scaffolding *g) { int i; #define SENSITIVITY(q)\ @@ -2524,81 +2682,52 @@ void nsgtk_scaffolding_set_sensitivity(struct gtk_scaffolding *g) #undef SENSITIVITY } -void nsgtk_scaffolding_initial_sensitivity(struct gtk_scaffolding *g) -{ - for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - if (g->buttons[i]->main != NULL) - gtk_widget_set_sensitive(GTK_WIDGET( - g->buttons[i]->main), - g->buttons[i]->sensitivity); - if (g->buttons[i]->rclick != NULL) - gtk_widget_set_sensitive(GTK_WIDGET( - g->buttons[i]->rclick), - g->buttons[i]->sensitivity); - if ((g->buttons[i]->location != -1) && - (g->buttons[i]->button != NULL)) - gtk_widget_set_sensitive(GTK_WIDGET( - g->buttons[i]->button), - g->buttons[i]->sensitivity); - if (g->buttons[i]->popup != NULL) - gtk_widget_set_sensitive(GTK_WIDGET( - g->buttons[i]->popup), - g->buttons[i]->sensitivity); - } - gtk_widget_set_sensitive(GTK_WIDGET(g->menu_bar->view_submenu->images_menuitem), FALSE); -} -/** - * Checks if a location is over a link. - * - * Side effect of this function is to set the global current_menu_ctx - */ -static bool is_menu_over_link(struct gtk_scaffolding *g, gdouble x, gdouble y) +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_context_menu(struct nsgtk_scaffolding *g, + gdouble x, + gdouble y) { - struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - - if ((bw->current_content != NULL) && - (content_get_type(bw->current_content) == CONTENT_HTML)) { - browser_window_get_contextual_content(bw, x, y, - ¤t_menu_ctx); - } + GtkMenu *gtkmenu; - if (current_menu_ctx.link_url == NULL) - return false; + /* update the global current_menu_ctx */ + browser_window_get_contextual_content( + nsgtk_get_browser_window(g->top_level), + x, y, ¤t_menu_ctx); - return true; -} -void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, gdouble x, gdouble y) -{ - if (is_menu_over_link(g, x, y)) { - popup_menu_show(g->menu_popup, false, true, false, false, false); + if (current_menu_ctx.link_url != NULL) { + /* menu is opening over a link */ + gtkmenu = g->link_menu->link_menu; } else { - popup_menu_hide(g->menu_popup, false, true, false, false, false); - } + gtkmenu = g->menu_popup->popup_menu; - nsgtk_scaffolding_update_edit_actions_sensitivity(g); + nsgtk_scaffolding_update_edit_actions_sensitivity(g); - if (!(g->buttons[COPY_BUTTON]->sensitivity)) - gtk_widget_hide(GTK_WIDGET(g->menu_popup->copy_menuitem)); - else - gtk_widget_show(GTK_WIDGET(g->menu_popup->copy_menuitem)); + if (!(g->buttons[COPY_BUTTON]->sensitivity)) { + gtk_widget_hide(GTK_WIDGET(g->menu_popup->copy_menuitem)); + } else { + gtk_widget_show(GTK_WIDGET(g->menu_popup->copy_menuitem)); + } - if (!(g->buttons[CUT_BUTTON]->sensitivity)) - gtk_widget_hide(GTK_WIDGET(g->menu_popup->cut_menuitem)); - else - gtk_widget_show(GTK_WIDGET(g->menu_popup->cut_menuitem)); + if (!(g->buttons[CUT_BUTTON]->sensitivity)) { + gtk_widget_hide(GTK_WIDGET(g->menu_popup->cut_menuitem)); + } else { + gtk_widget_show(GTK_WIDGET(g->menu_popup->cut_menuitem)); + } - if (!(g->buttons[PASTE_BUTTON]->sensitivity)) - gtk_widget_hide(GTK_WIDGET(g->menu_popup->paste_menuitem)); - else - gtk_widget_show(GTK_WIDGET(g->menu_popup->paste_menuitem)); + if (!(g->buttons[PASTE_BUTTON]->sensitivity)) { + gtk_widget_hide(GTK_WIDGET(g->menu_popup->paste_menuitem)); + } else { + gtk_widget_show(GTK_WIDGET(g->menu_popup->paste_menuitem)); + } - /* hide customize */ - popup_menu_hide(g->menu_popup, false, false, false, false, true); + /* hide customize */ + popup_menu_hide(g->menu_popup, false, false, false, true); + } - gtk_menu_popup(g->menu_popup->popup_menu, NULL, NULL, NULL, NULL, 0, - gtk_get_current_event_time()); + gtk_menu_popup(gtkmenu, NULL, NULL, NULL, NULL, 0, + gtk_get_current_event_time()); } /** @@ -2608,7 +2737,7 @@ void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, gdouble x, gdouble void nsgtk_scaffolding_toolbar_size_allocate(GtkWidget *widget, GtkAllocation *alloc, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; int i = nsgtk_toolbar_get_id_from_widget(widget, g); if (i == -1) return; @@ -2640,134 +2769,3 @@ void nsgtk_scaffolding_toolbar_size_allocate(GtkWidget *widget, -/** - * init the array g->buttons[] - */ -void nsgtk_scaffolding_toolbar_init(struct gtk_scaffolding *g) -{ -#define ITEM_MAIN(p, q, r)\ - g->buttons[p##_BUTTON]->main =\ - g->menu_bar->q->r##_menuitem;\ - g->buttons[p##_BUTTON]->rclick =\ - g->menu_popup->q->r##_menuitem;\ - g->buttons[p##_BUTTON]->mhandler =\ - nsgtk_on_##r##_activate_menu;\ - g->buttons[p##_BUTTON]->bhandler =\ - nsgtk_on_##r##_activate_button;\ - g->buttons[p##_BUTTON]->dataplus =\ - nsgtk_toolbar_##r##_button_data;\ - g->buttons[p##_BUTTON]->dataminus =\ - nsgtk_toolbar_##r##_toolbar_button_data - -#define ITEM_SUB(p, q, r, s)\ - g->buttons[p##_BUTTON]->main =\ - g->menu_bar->q->r##_submenu->s##_menuitem;\ - g->buttons[p##_BUTTON]->rclick =\ - g->menu_popup->q->r##_submenu->s##_menuitem;\ - g->buttons[p##_BUTTON]->mhandler =\ - nsgtk_on_##s##_activate_menu;\ - g->buttons[p##_BUTTON]->bhandler =\ - nsgtk_on_##s##_activate_button;\ - g->buttons[p##_BUTTON]->dataplus =\ - nsgtk_toolbar_##s##_button_data;\ - g->buttons[p##_BUTTON]->dataminus =\ - nsgtk_toolbar_##s##_toolbar_button_data - -#define ITEM_BUTTON(p, q)\ - g->buttons[p##_BUTTON]->bhandler =\ - nsgtk_on_##q##_activate;\ - g->buttons[p##_BUTTON]->dataplus =\ - nsgtk_toolbar_##q##_button_data;\ - g->buttons[p##_BUTTON]->dataminus =\ - nsgtk_toolbar_##q##_toolbar_button_data - -#define ITEM_POP(p, q) \ - g->buttons[p##_BUTTON]->popup = GTK_IMAGE_MENU_ITEM(\ - g->menu_popup->q##_menuitem) - -#define SENSITIVITY(q) \ - g->buttons[q##_BUTTON]->sensitivity = false - -#define ITEM_ITEM(p, q)\ - g->buttons[p##_ITEM]->dataplus =\ - nsgtk_toolbar_##q##_button_data;\ - g->buttons[p##_ITEM]->dataminus =\ - nsgtk_toolbar_##q##_toolbar_button_data - ITEM_ITEM(WEBSEARCH, websearch); - ITEM_ITEM(THROBBER, throbber); - ITEM_MAIN(NEWWINDOW, file_submenu, newwindow); - ITEM_MAIN(NEWTAB, file_submenu, newtab); - ITEM_MAIN(OPENFILE, file_submenu, openfile); - ITEM_MAIN(PRINT, file_submenu, print); - ITEM_MAIN(CLOSEWINDOW, file_submenu, closewindow); - ITEM_MAIN(SAVEPAGE, file_submenu, savepage); - ITEM_MAIN(PRINTPREVIEW, file_submenu, printpreview); - ITEM_MAIN(PRINT, file_submenu, print); - ITEM_MAIN(QUIT, file_submenu, quit); - ITEM_MAIN(CUT, edit_submenu, cut); - ITEM_MAIN(COPY, edit_submenu, copy); - ITEM_MAIN(PASTE, edit_submenu, paste); - ITEM_MAIN(DELETE, edit_submenu, delete); - ITEM_MAIN(SELECTALL, edit_submenu, selectall); - ITEM_MAIN(FIND, edit_submenu, find); - ITEM_MAIN(PREFERENCES, edit_submenu, preferences); - ITEM_MAIN(STOP, view_submenu, stop); - ITEM_POP(STOP, stop); - ITEM_MAIN(RELOAD, view_submenu, reload); - ITEM_POP(RELOAD, reload); - ITEM_MAIN(FULLSCREEN, view_submenu, fullscreen); - ITEM_MAIN(VIEWSOURCE, view_submenu, viewsource); - ITEM_MAIN(DOWNLOADS, view_submenu, downloads); - ITEM_MAIN(SAVEWINDOWSIZE, view_submenu, savewindowsize); - ITEM_MAIN(BACK, nav_submenu, back); - ITEM_POP(BACK, back); - ITEM_MAIN(FORWARD, nav_submenu, forward); - ITEM_POP(FORWARD, forward); - ITEM_MAIN(HOME, nav_submenu, home); - ITEM_MAIN(LOCALHISTORY, nav_submenu, localhistory); - ITEM_MAIN(GLOBALHISTORY, nav_submenu, globalhistory); - ITEM_MAIN(ADDBOOKMARKS, nav_submenu, addbookmarks); - ITEM_MAIN(SHOWBOOKMARKS, nav_submenu, showbookmarks); - ITEM_MAIN(SHOWCOOKIES, nav_submenu, showcookies); - ITEM_MAIN(OPENLOCATION, nav_submenu, openlocation); - ITEM_MAIN(CONTENTS, help_submenu, contents); - ITEM_MAIN(INFO, help_submenu, info); - ITEM_MAIN(GUIDE, help_submenu, guide); - ITEM_MAIN(ABOUT, help_submenu, about); - ITEM_SUB(PLAINTEXT, file_submenu, export, plaintext); - ITEM_SUB(PDF, file_submenu, export, pdf); - ITEM_SUB(DRAWFILE, file_submenu, export, drawfile); - ITEM_SUB(POSTSCRIPT, file_submenu, export, postscript); - ITEM_SUB(ZOOMPLUS, view_submenu, scaleview, zoomplus); - ITEM_SUB(ZOOMMINUS, view_submenu, scaleview, zoomminus); - ITEM_SUB(ZOOMNORMAL, view_submenu, scaleview, zoomnormal); - ITEM_SUB(NEXTTAB, view_submenu, tabs, nexttab); - ITEM_SUB(PREVTAB, view_submenu, tabs, prevtab); - ITEM_SUB(CLOSETAB, view_submenu, tabs, closetab); - ITEM_SUB(TOGGLEDEBUGGING, view_submenu, debugging, toggledebugging); - ITEM_SUB(SAVEBOXTREE, view_submenu, debugging, saveboxtree); - ITEM_SUB(SAVEDOMTREE, view_submenu, debugging, savedomtree); - ITEM_BUTTON(HISTORY, history); - /* disable items that make no sense initially, as well as - * as-yet-unimplemented items */ - SENSITIVITY(BACK); - SENSITIVITY(FORWARD); - SENSITIVITY(STOP); - SENSITIVITY(PRINTPREVIEW); - SENSITIVITY(DELETE); - SENSITIVITY(DRAWFILE); - SENSITIVITY(POSTSCRIPT); - SENSITIVITY(NEXTTAB); - SENSITIVITY(PREVTAB); - SENSITIVITY(CLOSETAB); -#ifndef WITH_PDF_EXPORT - SENSITIVITY(PDF); -#endif - -#undef ITEM_MAIN -#undef ITEM_SUB -#undef ITEM_BUTTON -#undef ITEM_POP -#undef SENSITIVITY - -} diff --git a/gtk/scaffolding.h b/gtk/scaffolding.h index 79e3fa0df..e7d945ebc 100644 --- a/gtk/scaffolding.h +++ b/gtk/scaffolding.h @@ -19,16 +19,15 @@ #ifndef NETSURF_GTK_SCAFFOLDING_H #define NETSURF_GTK_SCAFFOLDING_H 1 -#include <gtk/gtk.h> -//#include <glade/glade.h> -#include <glib.h> +#include <stdbool.h> +#include "utils/errors.h" -#include "desktop/gui.h" -#include "desktop/plotters.h" -#include "gtk/menu.h" -#include "gtk/sexy_icon_entry.h" +struct bitmap; +struct hlcache_handle; +struct gui_window; +struct gui_search_web_table; -typedef struct gtk_scaffolding nsgtk_scaffolding; +extern struct gui_search_web_table *nsgtk_search_web_table; typedef enum { BACK_BUTTON = 0, @@ -86,7 +85,7 @@ typedef enum { } nsgtk_toolbar_button; /* PLACEHOLDER_BUTTON - 1 */ struct gtk_history_window { - struct gtk_scaffolding *g; + struct nsgtk_scaffolding *g; GtkWindow *window; GtkScrolledWindow *scrolled; GtkDrawingArea *drawing_area; @@ -113,38 +112,88 @@ struct nsgtk_button_connect { void *dataminus; /* customization -> store */ }; -extern nsgtk_scaffolding *scaf_list; - -nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel); - -bool nsgtk_scaffolding_is_busy(nsgtk_scaffolding *g); - -GtkWindow *nsgtk_scaffolding_window(nsgtk_scaffolding *g); -GtkNotebook *nsgtk_scaffolding_notebook(nsgtk_scaffolding *g); -GtkWidget *nsgtk_scaffolding_urlbar(nsgtk_scaffolding *g); -GtkWidget *nsgtk_scaffolding_websearch(nsgtk_scaffolding *g); -GtkToolbar *nsgtk_scaffolding_toolbar(nsgtk_scaffolding *g); -struct nsgtk_button_connect *nsgtk_scaffolding_button(nsgtk_scaffolding *g, - int i); -struct gtk_search *nsgtk_scaffolding_search(nsgtk_scaffolding *g); -GtkMenuBar *nsgtk_scaffolding_menu_bar(nsgtk_scaffolding *g); -struct gtk_history_window *nsgtk_scaffolding_history_window(nsgtk_scaffolding - *g); -struct gui_window *nsgtk_scaffolding_top_level(nsgtk_scaffolding *g); -void nsgtk_scaffolding_reset_offset(nsgtk_scaffolding *g); -nsgtk_scaffolding *nsgtk_scaffolding_iterate(nsgtk_scaffolding *g); -void nsgtk_scaffolding_toolbar_init(struct gtk_scaffolding *g); -void nsgtk_scaffolding_update_url_bar_ref(nsgtk_scaffolding *g); -void nsgtk_scaffolding_update_throbber_ref(nsgtk_scaffolding *g); -void nsgtk_scaffolding_update_websearch_ref(nsgtk_scaffolding *g); -void nsgtk_scaffolding_set_websearch(nsgtk_scaffolding *g, const char - *content); -void nsgtk_scaffolding_toggle_search_bar_visibility(nsgtk_scaffolding *g); -void nsgtk_scaffolding_set_top_level(struct gui_window *g); +/** + * create a new scaffolding for a window. + * + * \param gw The gui window to create the new scaffold around. + * \return The newly constructed scaffold or NULL on error. + */ +struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *gw); + +/** + * Obtain the most recently used scaffolding element. + * + * This allows tabs to be opened in the most recently used window + */ +struct nsgtk_scaffolding *nsgtk_current_scaffolding(void); + +/* acessors for gtk elements withing a scaffold */ + +/** + * Get the gtk window for a scaffolding. + */ +GtkWindow *nsgtk_scaffolding_window(struct nsgtk_scaffolding *g); + +/** + * Get the gtk notebook from a scaffold. + */ +GtkNotebook *nsgtk_scaffolding_notebook(struct nsgtk_scaffolding *g); + +/** + * Get the gtk url bar from a scaffold. + */ +GtkWidget *nsgtk_scaffolding_urlbar(struct nsgtk_scaffolding *g); + +/** + * Get the gtk web search entry from a scaffold. + */ +GtkWidget *nsgtk_scaffolding_websearch(struct nsgtk_scaffolding *g); + +/** + * Get the gtk toolbar from a scaffold. + */ +GtkToolbar *nsgtk_scaffolding_toolbar(struct nsgtk_scaffolding *g); + + +struct nsgtk_button_connect *nsgtk_scaffolding_button(struct nsgtk_scaffolding *g, int i); + +struct gtk_search *nsgtk_scaffolding_search(struct nsgtk_scaffolding *g); + +GtkMenuBar *nsgtk_scaffolding_menu_bar(struct nsgtk_scaffolding *g); -void nsgtk_scaffolding_destroy(nsgtk_scaffolding *g); +struct gtk_history_window *nsgtk_scaffolding_history_window(struct nsgtk_scaffolding *g); -/** update the sensitivity of context sensitive UI elements +struct gui_window *nsgtk_scaffolding_top_level(struct nsgtk_scaffolding *g); + +/** + * reset the scaffold offset value to 0. + * + * \todo The value is only ever altered in + * nsgtk_scaffolding_toolbar_size_allocate and is something to do with + * the history button either clarify or remove! + */ +void nsgtk_scaffolding_reset_offset(struct nsgtk_scaffolding *g); + +/** + * Iterate through available scaffolding. + */ +struct nsgtk_scaffolding *nsgtk_scaffolding_iterate(struct nsgtk_scaffolding *g); + +void nsgtk_scaffolding_update_url_bar_ref(struct nsgtk_scaffolding *g); + +void nsgtk_scaffolding_update_throbber_ref(struct nsgtk_scaffolding *g); + +void nsgtk_scaffolding_update_websearch_ref(struct nsgtk_scaffolding *g); + +void nsgtk_scaffolding_toggle_search_bar_visibility(struct nsgtk_scaffolding *g); + +/** + * Set the current active top level gui window. + */ +void nsgtk_scaffolding_set_top_level(struct gui_window *g); + +/** + * update the sensitivity of context sensitive UI elements * * widgets altered in arrays: * main @@ -163,18 +212,32 @@ void nsgtk_scaffolding_destroy(nsgtk_scaffolding *g); * prevtab * closetab */ -void nsgtk_scaffolding_set_sensitivity(struct gtk_scaffolding *g); +void nsgtk_scaffolding_set_sensitivity(struct nsgtk_scaffolding *g); + +/** + * Open a context sensitive menu. + * + * \param g the scaffolding containing the browser window. + * \param x The x co-ordinate. + * \param y The y co-ordinate. + */ +void nsgtk_scaffolding_context_menu(struct nsgtk_scaffolding *g, gdouble x, gdouble y); + +void nsgtk_scaffolding_toolbar_size_allocate(GtkWidget *widget, GtkAllocation *alloc, gpointer data); -void nsgtk_scaffolding_initial_sensitivity(struct gtk_scaffolding *g); -void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, gdouble x, - gdouble y); -void nsgtk_scaffolding_toolbar_size_allocate(GtkWidget *widget, - GtkAllocation *alloc, gpointer data); void nsgtk_scaffolding_set_icon(struct gui_window *gw); gboolean nsgtk_window_url_activate_event(GtkWidget *, gpointer); + gboolean nsgtk_window_url_changed(GtkWidget *, GdkEventKey *, gpointer); nserror nsgtk_scaffolding_new_tab(struct gui_window *gw); +/* core acessors */ +void gui_window_set_title(struct gui_window *g, const char *title); +void gui_window_set_url(struct gui_window *g, const char *url); +void gui_window_start_throbber(struct gui_window *g); +void gui_window_stop_throbber(struct gui_window *g); + + #endif /* NETSURF_GTK_SCAFFOLDING_H */ diff --git a/gtk/schedule.c b/gtk/schedule.c index 5b168b689..e28675a0b 100644 --- a/gtk/schedule.c +++ b/gtk/schedule.c @@ -20,7 +20,8 @@ #include <stdlib.h> #include <stdbool.h> -#include "utils/schedule.h" +#include "utils/errors.h" + #include "gtk/schedule.h" #ifdef DEBUG_GTK_SCHEDULE @@ -71,7 +72,7 @@ nsgtk_schedule_kill_callback(void *_target, void *_match) } } -void +static void schedule_remove(void (*callback)(void *p), void *p) { _nsgtk_callback_t cb_match = { @@ -87,19 +88,27 @@ schedule_remove(void (*callback)(void *p), void *p) nsgtk_schedule_kill_callback, &cb_match); } -void -schedule(int t, void (*callback)(void *p), void *p) +/* exported interface documented in gtk/schedule.h */ +nserror nsgtk_schedule(int t, void (*callback)(void *p), void *p) { - const int msec_timeout = t * 10; - _nsgtk_callback_t *cb = malloc(sizeof(_nsgtk_callback_t)); + _nsgtk_callback_t *cb; + /* Kill any pending schedule of this kind. */ schedule_remove(callback, p); + + if (t < 0) { + return NSERROR_OK; + } + + cb = malloc(sizeof(_nsgtk_callback_t)); cb->callback = callback; cb->context = p; cb->callback_killed = false; /* Prepend is faster right now. */ queued_callbacks = g_list_prepend(queued_callbacks, cb); - g_timeout_add(msec_timeout, nsgtk_schedule_generic_callback, cb); + g_timeout_add(t, nsgtk_schedule_generic_callback, cb); + + return NSERROR_OK; } bool diff --git a/gtk/schedule.h b/gtk/schedule.h index c63215e88..0a2d724d4 100644 --- a/gtk/schedule.h +++ b/gtk/schedule.h @@ -19,7 +19,8 @@ #ifndef NETSURF_GTK_CALLBACK_H #define NETSURF_GTK_CALLBACK_H 1 -typedef void (*gtk_callback)(void *p); +nserror nsgtk_schedule(int t, void (*callback)(void *p), void *p); + bool schedule_run(void); #endif /* NETSURF_GTK_CALLBACK_H */ diff --git a/gtk/search.c b/gtk/search.c index d4fbadcc8..02bfed713 100644 --- a/gtk/search.c +++ b/gtk/search.c @@ -25,14 +25,10 @@ #include <string.h> #include <gdk/gdkkeysyms.h> -#include "gtk/compat.h" -#include "gtk/search.h" -#include "gtk/scaffolding.h" -#include "gtk/window.h" #include "utils/config.h" #include "content/content.h" #include "content/hlcache.h" -#include "desktop/browser_private.h" +#include "desktop/browser.h" #include "desktop/gui.h" #include "desktop/search.h" #include "desktop/searchweb.h" @@ -40,25 +36,49 @@ #include "utils/messages.h" #include "utils/utils.h" -static void nsgtk_search_set_status(bool found, void *p); -static void nsgtk_search_set_hourglass(bool active, void *p); -static void nsgtk_search_add_recent(const char *string, void *p); +#include "gtk/compat.h" +#include "gtk/search.h" +#include "gtk/scaffolding.h" +#include "gtk/window.h" -static struct gui_search_callbacks nsgtk_search_callbacks = { - nsgtk_search_set_forward_state, - nsgtk_search_set_back_state, - nsgtk_search_set_status, - nsgtk_search_set_hourglass, - nsgtk_search_add_recent -}; +/** + * activate search forwards button in gui. + * + * \param active activate/inactivate + * \param p the pointer sent to search_verify_new() / search_create_context() + */ +static void nsgtk_search_set_forward_state(bool active, struct gui_window *gw) +{ + if (gw != NULL && nsgtk_get_browser_window(gw) != NULL) { + struct nsgtk_scaffolding *g = nsgtk_get_scaffold(gw); + gtk_widget_set_sensitive( + GTK_WIDGET(nsgtk_scaffolding_search(g)->buttons[1]), + active); + } +} + +/** + * activate search back button in gui. + * + * \param active activate/inactivate + * \param p the pointer sent to search_verify_new() / search_create_context() + */ +static void nsgtk_search_set_back_state(bool active, struct gui_window *gw) +{ + if (gw != NULL && nsgtk_get_browser_window(gw) != NULL) { + struct nsgtk_scaffolding *g = nsgtk_get_scaffold(gw); + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_search( + g)->buttons[0]), active); + } +} /** connected to the search forward button */ gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; - struct browser_window *bw = nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(g)); + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + struct gui_window *gw = nsgtk_scaffolding_top_level(g); + struct browser_window *bw = nsgtk_get_browser_window(gw); assert(bw); @@ -70,7 +90,7 @@ gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data) nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + browser_window_search(bw, gw, flags, gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } @@ -79,9 +99,9 @@ gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data) gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; - struct browser_window *bw = nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(g)); + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + struct gui_window *gw = nsgtk_scaffolding_top_level(g); + struct browser_window *bw = nsgtk_get_browser_window(gw); assert(bw); @@ -93,7 +113,7 @@ gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data) nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + browser_window_search(bw, gw, flags, gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } @@ -102,7 +122,7 @@ gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data) gboolean nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; nsgtk_scaffolding_toggle_search_bar_visibility(g); return TRUE; } @@ -111,24 +131,25 @@ gboolean nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data) gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; - struct browser_window *bw = nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(g)); + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + struct gui_window *gw = nsgtk_scaffolding_top_level(g); + struct browser_window *bw = nsgtk_get_browser_window(gw); + search_flags_t flags; assert(bw != NULL); - nsgtk_search_set_forward_state(true, (void *)bw); - nsgtk_search_set_back_state(true, (void *)bw); + nsgtk_search_set_forward_state(true, gw); + nsgtk_search_set_back_state(true, gw); - search_flags_t flags = SEARCH_FLAG_FORWARDS | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + flags = SEARCH_FLAG_FORWARDS | + (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( nsgtk_scaffolding_search(g)->caseSens)) ? SEARCH_FLAG_CASE_SENSITIVE : 0) | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + browser_window_search(bw, gw, flags, gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } @@ -137,32 +158,33 @@ gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data) gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; - struct browser_window *bw = nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(g)); + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + struct gui_window *gw = nsgtk_scaffolding_top_level(g); + struct browser_window *bw = nsgtk_get_browser_window(gw); + search_flags_t flags; assert(bw); - search_flags_t flags = SEARCH_FLAG_FORWARDS | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + flags = SEARCH_FLAG_FORWARDS | + (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( nsgtk_scaffolding_search(g)->caseSens)) ? SEARCH_FLAG_CASE_SENSITIVE : 0) | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + browser_window_search(bw, gw, flags, gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return FALSE; } /** allows escape key to close search bar too */ -gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event, - gpointer data) +gboolean +nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_KEY(Escape)) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; nsgtk_scaffolding_toggle_search_bar_visibility(g); } return FALSE; @@ -172,13 +194,29 @@ gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event, gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; - temp_open_background = 0; - search_web_new_window(nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(g)), - (char *)gtk_entry_get_text(GTK_ENTRY( - nsgtk_scaffolding_websearch(g)))); - temp_open_background = -1; + struct nsgtk_scaffolding *g = data; + nserror ret; + nsurl *url; + + ret = search_web_omni( + gtk_entry_get_text(GTK_ENTRY(nsgtk_scaffolding_websearch(g))), + SEARCH_WEB_OMNI_SEARCHONLY, + &url); + if (ret == NSERROR_OK) { + temp_open_background = 0; + ret = browser_window_create( + BW_CREATE_HISTORY | BW_CREATE_TAB, + url, + NULL, + nsgtk_get_browser_window(nsgtk_scaffolding_top_level(g)), + NULL); + temp_open_background = -1; + nsurl_unref(url); + } + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); + } + return TRUE; } @@ -190,74 +228,18 @@ gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data) gboolean nsgtk_websearch_clear(GtkWidget *widget, GdkEventFocus *f, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; gtk_editable_select_region(GTK_EDITABLE( nsgtk_scaffolding_websearch(g)), 0, -1); gtk_widget_grab_focus(GTK_WIDGET(nsgtk_scaffolding_websearch(g))); return TRUE; } -/** -* Change the displayed search status. -* \param found search pattern matched in text -* \param p the pointer sent to search_verify_new() / search_create_context() -*/ - -void nsgtk_search_set_status(bool found, void *p) -{ -} - -/** -* display hourglass while searching -* \param active start/stop indicator -* \param p the pointer sent to search_verify_new() / search_create_context() -*/ - -void nsgtk_search_set_hourglass(bool active, void *p) -{ -} - -/** -* add search string to recent searches list -* front is at liberty how to implement the bare notification -* should normally store a strdup() of the string; -* core gives no guarantee of the integrity of the const char * -* \param string search pattern -* \param p the pointer sent to search_verify_new() / search_create_context() -*/ - -void nsgtk_search_add_recent(const char *string, void *p) -{ -} - -/** -* activate search forwards button in gui -* \param active activate/inactivate -* \param p the pointer sent to search_verify_new() / search_create_context() -*/ -void nsgtk_search_set_forward_state(bool active, void *p) -{ - struct browser_window *bw = (struct browser_window *)p; - if ((bw != NULL) && (bw->window != NULL)) { - struct gtk_scaffolding *g = nsgtk_get_scaffold(bw->window); - gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_search( - g)->buttons[1]), active); - } -} -/** -* activate search back button in gui -* \param active activate/inactivate -* \param p the pointer sent to search_verify_new() / search_create_context() -*/ +static struct gui_search_table search_table = { + .forward_state = (void *)nsgtk_search_set_forward_state, + .back_state = (void *)nsgtk_search_set_back_state, +}; -void nsgtk_search_set_back_state(bool active, void *p) -{ - struct browser_window *bw = (struct browser_window *)p; - if ((bw != NULL) && (bw->window != NULL)) { - struct gtk_scaffolding *g = nsgtk_get_scaffold(bw->window); - gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_search( - g)->buttons[0]), active); - } -} +struct gui_search_table *nsgtk_search_table = &search_table; diff --git a/gtk/search.h b/gtk/search.h index 869a3cd8a..dd8c60d0f 100644 --- a/gtk/search.h +++ b/gtk/search.h @@ -19,21 +19,18 @@ #ifndef _NETSURF_GTK_SEARCH_H_ #define _NETSURF_GTK_SEARCH_H_ -#include <gtk/gtk.h> -#include "gtk/scaffolding.h" +struct gui_search_table *nsgtk_search_table; -void nsgtk_search_bar_toggle_visibility(struct gtk_scaffolding * g); +struct nsgtk_scaffolding; + +void nsgtk_search_bar_toggle_visibility(struct nsgtk_scaffolding * g); gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data); gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data); -gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event, - gpointer data); +gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event, gpointer data); gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data); gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data); gboolean nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data); gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data); -gboolean nsgtk_websearch_clear(GtkWidget *widget, GdkEventFocus *f, - gpointer data); -void nsgtk_search_set_forward_state(bool active, void *p); -void nsgtk_search_set_back_state(bool active, void *p); +gboolean nsgtk_websearch_clear(GtkWidget *widget, GdkEventFocus *f, gpointer data); #endif diff --git a/gtk/selection.c b/gtk/selection.c index b0978b385..231e5fd0d 100644 --- a/gtk/selection.c +++ b/gtk/selection.c @@ -18,36 +18,25 @@ #include <string.h> #include <gtk/gtk.h> +#include <stdlib.h> #include "utils/log.h" - -#include "desktop/gui.h" #include "desktop/browser.h" -#include "gtk/selection.h" +#include "desktop/gui.h" + #include "gtk/window.h" static GString *current_selection = NULL; static GtkClipboard *clipboard; - - -void gui_start_selection(struct gui_window *g) -{ - gtk_widget_grab_focus(GTK_WIDGET(nsgtk_window_get_layout(g))); -} - -void gui_clear_selection(struct gui_window *g) -{ -} - /** * Core asks front end for clipboard contents. * * \param buffer UTF-8 text, allocated by front end, ownership yeilded to core * \param length Byte length of UTF-8 text in buffer */ -void gui_get_clipboard(char **buffer, size_t *length) +static void gui_get_clipboard(char **buffer, size_t *length) { gchar *gtext; @@ -83,7 +72,7 @@ void gui_get_clipboard(char **buffer, size_t *length) * \param styles Array of styles given to text runs, owned by core, or NULL * \param n_styles Number of text run styles in array */ -void gui_set_clipboard(const char *buffer, size_t length, +static void gui_set_clipboard(const char *buffer, size_t length, nsclipboard_styles styles[], int n_styles) { clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); @@ -99,3 +88,9 @@ void gui_set_clipboard(const char *buffer, size_t length, gtk_clipboard_set_text(clipboard, current_selection->str, -1); } +static struct gui_clipboard_table clipboard_table = { + .get = gui_get_clipboard, + .set = gui_set_clipboard, +}; + +struct gui_clipboard_table *nsgtk_clipboard_table = &clipboard_table; diff --git a/gtk/selection.h b/gtk/selection.h index c2a0b35f4..6463692cf 100644 --- a/gtk/selection.h +++ b/gtk/selection.h @@ -19,7 +19,6 @@ #ifndef GTK_SELECTION_H #define GTK_SELECTION_H -#include <gtk/gtk.h> -#include "desktop/gui.h" +struct gui_clipboard_table *nsgtk_clipboard_table; #endif diff --git a/gtk/tabs.c b/gtk/tabs.c index 62a864ed1..f8d560cf1 100644 --- a/gtk/tabs.c +++ b/gtk/tabs.c @@ -266,7 +266,7 @@ void nsgtk_tab_options_changed(GtkNotebook *notebook) /* exported interface documented in gtk/tabs.h */ -void nsgtk_tab_init(struct gtk_scaffolding *gs) +void nsgtk_tab_init(struct nsgtk_scaffolding *gs) { GtkNotebook *notebook; diff --git a/gtk/tabs.h b/gtk/tabs.h index caa683e40..036efb1e5 100644 --- a/gtk/tabs.h +++ b/gtk/tabs.h @@ -21,7 +21,7 @@ struct gui_window; -void nsgtk_tab_init(struct gtk_scaffolding *gs); +void nsgtk_tab_init(struct nsgtk_scaffolding *gs); void nsgtk_tab_add(struct gui_window *window, GtkWidget *tab_contents, bool background); /** set the tab title diff --git a/gtk/theme.c b/gtk/theme.c index 9d50c5931..dd034ac8b 100644 --- a/gtk/theme.c +++ b/gtk/theme.c @@ -22,21 +22,24 @@ #include <sys/stat.h> #include <unistd.h> +#include "utils/config.h" +#include "utils/nsoption.h" +#include "utils/container.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "desktop/browser.h" #include "content/content.h" #include "content/content_type.h" #include "content/hlcache.h" + #include "gtk/compat.h" #include "gtk/gui.h" #include "gtk/scaffolding.h" #include "gtk/menu.h" #include "gtk/theme.h" #include "gtk/window.h" -#include "utils/nsoption.h" #include "gtk/dialogs/preferences.h" -#include "utils/container.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" enum image_sets { IMAGE_SET_MAIN_MENU = 0, @@ -158,7 +161,7 @@ static bool nsgtk_theme_verify(const char *themename) void nsgtk_theme_init(void) { int theme; - nsgtk_scaffolding *list = scaf_list; + struct nsgtk_scaffolding *list; FILE *fp; char buf[50]; int row_count = 0; @@ -191,6 +194,7 @@ void nsgtk_theme_init(void) } fclose(fp); + list = nsgtk_scaffolding_iterate(NULL); while (list != NULL) { nsgtk_theme_implement(list); list = nsgtk_scaffolding_iterate(list); @@ -284,7 +288,7 @@ void nsgtk_theme_add(const char *themename) * sets the images for a particular scaffolding according to the current theme */ -void nsgtk_theme_implement(struct gtk_scaffolding *g) +void nsgtk_theme_implement(struct nsgtk_scaffolding *g) { struct nsgtk_theme *theme[IMAGE_SET_COUNT]; int i; @@ -793,11 +797,8 @@ theme_install_callback(hlcache_handle *c, const hlcache_event *event, void *pw) { switch (event->type) { - case CONTENT_MSG_READY: - break; - case CONTENT_MSG_DONE: - { + case CONTENT_MSG_DONE: { const char *source_data; unsigned long source_size; @@ -807,21 +808,14 @@ theme_install_callback(hlcache_handle *c, warn_user("ThemeInvalid", 0); hlcache_handle_release(c); + break; } - break; case CONTENT_MSG_ERROR: warn_user(event->data.error, 0); break; - case CONTENT_MSG_STATUS: - break; - - case CONTENT_MSG_LOADING: - case CONTENT_MSG_REFORMAT: - case CONTENT_MSG_REDRAW: default: - assert(0); break; } diff --git a/gtk/theme.h b/gtk/theme.h index 4aedad23f..175757b4a 100644 --- a/gtk/theme.h +++ b/gtk/theme.h @@ -39,7 +39,7 @@ struct nsgtk_theme *nsgtk_theme_load(GtkIconSize s); void nsgtk_theme_add(const char *themename); void nsgtk_theme_init(void); void nsgtk_theme_prepare(void); -void nsgtk_theme_implement(struct gtk_scaffolding *g); +void nsgtk_theme_implement(struct nsgtk_scaffolding *g); char *nsgtk_theme_name(void); void nsgtk_theme_set_name(const char *name); diff --git a/gtk/toolbar.c b/gtk/toolbar.c index d543ca5fd..845344757 100644 --- a/gtk/toolbar.c +++ b/gtk/toolbar.c @@ -16,9 +16,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <string.h> #include <gtk/gtk.h> -#include "desktop/browser_private.h" +#include "desktop/browser.h" #include "desktop/searchweb.h" #include "utils/log.h" #include "utils/messages.h" @@ -66,11 +67,10 @@ possible into the store */ static struct nsgtk_toolbar_custom_store store; static struct nsgtk_toolbar_custom_store *window = &store; -static void nsgtk_toolbar_close(nsgtk_scaffolding *g); -static void nsgtk_toolbar_window_open(nsgtk_scaffolding *g); -static void nsgtk_toolbar_customization_save(nsgtk_scaffolding *g); -static void nsgtk_toolbar_add_item_to_toolbar(nsgtk_scaffolding *g, int i, - struct nsgtk_theme *theme); +static void nsgtk_toolbar_close(struct nsgtk_scaffolding *g); +static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g); +static void nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g); +static void nsgtk_toolbar_add_item_to_toolbar(struct nsgtk_scaffolding *g, int i, struct nsgtk_theme *theme); static bool nsgtk_toolbar_add_store_widget(GtkWidget *widget); static gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data); @@ -89,28 +89,30 @@ static gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, static gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data); static gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data); static gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data); -static void nsgtk_toolbar_cast(nsgtk_scaffolding *g); -static GtkWidget *nsgtk_toolbar_make_widget(nsgtk_scaffolding *g, +static void nsgtk_toolbar_cast(struct nsgtk_scaffolding *g); +static GtkWidget *nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i, struct nsgtk_theme *theme); -static void nsgtk_toolbar_set_handler(nsgtk_scaffolding *g, +static void nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i); -static void nsgtk_toolbar_temp_connect(nsgtk_scaffolding *g, +static void nsgtk_toolbar_temp_connect(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i); static void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data); static nsgtk_toolbar_button nsgtk_toolbar_get_id_at_location( - nsgtk_scaffolding *g, int i); + struct nsgtk_scaffolding *g, int i); /** - * change behaviour of scaffoldings while editing toolbar; all buttons as - * well as window clicks are desensitized; then buttons in the front window - * are changed to movable buttons + * change behaviour of scaffoldings while editing toolbar + * + * All buttons as well as window clicks are desensitized; then buttons + * in the front window are changed to movable buttons */ -void nsgtk_toolbar_customization_init(nsgtk_scaffolding *g) +void nsgtk_toolbar_customization_init(struct nsgtk_scaffolding *g) { int i; - nsgtk_scaffolding *list = scaf_list; + struct nsgtk_scaffolding *list; edit_mode = true; + list = nsgtk_scaffolding_iterate(NULL); while (list) { g_signal_handler_block(GTK_WIDGET( nsgtk_window_get_layout( @@ -186,7 +188,7 @@ void nsgtk_toolbar_customization_init(nsgtk_scaffolding *g) /** * create store window */ -void nsgtk_toolbar_window_open(nsgtk_scaffolding *g) +void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g) { int x = 0, y = 0; GError* error = NULL; @@ -285,7 +287,7 @@ gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, gpointer data) { edit_mode = false; - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; /* reset g->buttons->location */ for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { nsgtk_scaffolding_button(g, i)->location = @@ -305,7 +307,7 @@ gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data) { edit_mode = false; - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; /* reset g->buttons->location */ for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { nsgtk_scaffolding_button(g, i)->location = @@ -325,7 +327,7 @@ gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data) gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data) { edit_mode = false; - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; /* save state to file, update toolbars for all windows */ nsgtk_toolbar_customization_save(g); nsgtk_toolbar_cast(g); @@ -340,7 +342,7 @@ gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data) */ gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; int i; for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) nsgtk_scaffolding_button(g, i)->location = @@ -364,7 +366,7 @@ gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data) * to correspond to the logically stored schema in terms of location * visibility etc */ -void nsgtk_toolbar_set_physical(nsgtk_scaffolding *g) +void nsgtk_toolbar_set_physical(struct nsgtk_scaffolding *g) { int i; struct nsgtk_theme *theme = @@ -386,13 +388,16 @@ void nsgtk_toolbar_set_physical(nsgtk_scaffolding *g) * cleanup code physical update of all toolbars; resensitize * \param g the 'front' scaffolding that called customize */ -void nsgtk_toolbar_close(nsgtk_scaffolding *g) +void nsgtk_toolbar_close(struct nsgtk_scaffolding *g) { int i; - nsgtk_scaffolding *list = scaf_list; + + struct nsgtk_scaffolding *list; + struct nsgtk_theme *theme; + + list = nsgtk_scaffolding_iterate(NULL); while (list) { - struct nsgtk_theme *theme = - nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); + theme = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); if (theme == NULL) { warn_user(messages_get("NoMemory"), 0); continue; @@ -421,21 +426,9 @@ void nsgtk_toolbar_close(nsgtk_scaffolding *g) nsgtk_window_get_signalhandler( nsgtk_scaffolding_top_level(list), NSGTK_WINDOW_SIGNAL_REDRAW)); - if ((nsgtk_get_browser_window(nsgtk_scaffolding_top_level( - list))->current_content != NULL) && - (hlcache_handle_get_url(nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(list))-> - current_content) != NULL)) - browser_window_refresh_url_bar( - nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(list)), - hlcache_handle_get_url( - nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(list))-> - current_content), - nsgtk_get_browser_window( - nsgtk_scaffolding_top_level(list))-> - frag_id); + browser_window_refresh_url_bar( + nsgtk_get_browser_window( + nsgtk_scaffolding_top_level(list))); if (list != g) gtk_widget_set_sensitive(GTK_WIDGET( @@ -449,8 +442,8 @@ void nsgtk_toolbar_close(nsgtk_scaffolding *g) TRUE); /* update favicon etc */ nsgtk_scaffolding_set_top_level(nsgtk_scaffolding_top_level(g)); - if (search_web_ico()) - gui_window_set_search_ico(search_web_ico()); + + search_web_select_provider(-1); } /** @@ -458,7 +451,7 @@ void nsgtk_toolbar_close(nsgtk_scaffolding *g) */ void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; gtk_container_remove(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), widget); } @@ -469,7 +462,7 @@ void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data) * the function should be called, when multiple items are being added, * in ascending order */ -void nsgtk_toolbar_add_item_to_toolbar(nsgtk_scaffolding *g, int i, +void nsgtk_toolbar_add_item_to_toolbar(struct nsgtk_scaffolding *g, int i, struct nsgtk_theme *theme) { int q; @@ -521,7 +514,7 @@ bool nsgtk_toolbar_add_store_widget(GtkWidget *widget) gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; int ind = gtk_toolbar_get_drop_index(nsgtk_scaffolding_toolbar(g), x, y); int q, i; @@ -613,7 +606,7 @@ gboolean nsgtk_toolbar_move_complete(GtkWidget *widget, GdkDragContext *gdc, gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; int q, i; if ((window->fromstore) || (window->currentbutton == -1)) { @@ -648,7 +641,7 @@ gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, gboolean nsgtk_toolbar_action(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { - nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; GtkToolItem *item = gtk_tool_button_new(NULL, NULL); if (item != NULL) gtk_toolbar_set_drop_highlight_item( @@ -682,7 +675,7 @@ void nsgtk_toolbar_clear(GtkWidget *widget, GdkDragContext *gdc, guint time, * \param i the id of the widget * \param theme the theme to make the widgets from */ -GtkWidget *nsgtk_toolbar_make_widget(nsgtk_scaffolding *g, +GtkWidget *nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i, struct nsgtk_theme *theme) { switch(i) { @@ -818,8 +811,8 @@ GtkWidget *nsgtk_toolbar_make_widget(nsgtk_scaffolding *g, MAKE_MENUBUTTON(DOWNLOADS, gtkDownloads) MAKE_MENUBUTTON(SAVEWINDOWSIZE, gtkSaveWindowSize) MAKE_MENUBUTTON(TOGGLEDEBUGGING, gtkToggleDebugging) - MAKE_MENUBUTTON(SAVEBOXTREE, gtkSaveBoxTree) - MAKE_MENUBUTTON(SAVEDOMTREE, gtkSaveDomTree) + MAKE_MENUBUTTON(SAVEBOXTREE, gtkDebugBoxTree) + MAKE_MENUBUTTON(SAVEDOMTREE, gtkDebugDomTree) MAKE_MENUBUTTON(LOCALHISTORY, gtkLocalHistory) MAKE_MENUBUTTON(GLOBALHISTORY, gtkGlobalHistory) MAKE_MENUBUTTON(ADDBOOKMARKS, gtkAddBookMarks) @@ -840,7 +833,7 @@ GtkWidget *nsgtk_toolbar_make_widget(nsgtk_scaffolding *g, * \return toolbar item id when a widget is an element of the scaffolding * else -1 */ -int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, nsgtk_scaffolding *g) +int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, struct nsgtk_scaffolding *g) { int i; for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { @@ -857,8 +850,8 @@ int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, nsgtk_scaffolding *g) * \return toolbar item id from location when there is an item at that logical * location; else -1 */ -nsgtk_toolbar_button nsgtk_toolbar_get_id_at_location(nsgtk_scaffolding *g, - int i) +nsgtk_toolbar_button +nsgtk_toolbar_get_id_at_location(struct nsgtk_scaffolding *g, int i) { int q; for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) @@ -871,7 +864,7 @@ nsgtk_toolbar_button nsgtk_toolbar_get_id_at_location(nsgtk_scaffolding *g, * connect 'normal' handlers to toolbar buttons */ -void nsgtk_toolbar_connect_all(nsgtk_scaffolding *g) +void nsgtk_toolbar_connect_all(struct nsgtk_scaffolding *g) { int q, i; for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { @@ -893,7 +886,8 @@ void nsgtk_toolbar_connect_all(nsgtk_scaffolding *g) * \param g the scaffolding to attach handlers to * \param i the toolbar item id */ -void nsgtk_toolbar_set_handler(nsgtk_scaffolding *g, nsgtk_toolbar_button i) +void +nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) { switch(i){ case URL_BAR_ITEM: @@ -983,8 +977,8 @@ DATAHANDLER(find, FIND, window) DATAHANDLER(downloads, DOWNLOADS, window) DATAHANDLER(savewindowsize, SAVEWINDOWSIZE, window) DATAHANDLER(toggledebugging, TOGGLEDEBUGGING, window) -DATAHANDLER(saveboxtree, SAVEBOXTREE, window) -DATAHANDLER(savedomtree, SAVEDOMTREE, window) +DATAHANDLER(debugboxtree, SAVEBOXTREE, window) +DATAHANDLER(debugdomtree, SAVEDOMTREE, window) DATAHANDLER(localhistory, LOCALHISTORY, window) DATAHANDLER(globalhistory, GLOBALHISTORY, window) DATAHANDLER(addbookmarks, ADDBOOKMARKS, window) @@ -1021,7 +1015,7 @@ DATAHANDLER(websearch, WEBSEARCH, window) /** * connect temporary handler for toolbar edit events */ -void nsgtk_toolbar_temp_connect(nsgtk_scaffolding *g, nsgtk_toolbar_button i) +void nsgtk_toolbar_temp_connect(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) { if ((i == URL_BAR_ITEM) || (nsgtk_scaffolding_button(g, i)->button == NULL) || @@ -1036,7 +1030,7 @@ void nsgtk_toolbar_temp_connect(nsgtk_scaffolding *g, nsgtk_toolbar_button i) * load toolbar settings from file; file is a set of fields arranged as * [itemreference];[itemlocation]|[itemreference];[itemlocation]| etc */ -void nsgtk_toolbar_customization_load(nsgtk_scaffolding *g) +void nsgtk_toolbar_customization_load(struct nsgtk_scaffolding *g) { int i, ii; char *val; @@ -1077,17 +1071,21 @@ void nsgtk_toolbar_customization_load(nsgtk_scaffolding *g) * cast toolbar settings to all scaffoldings referenced from the global linked * list of gui_windows */ -void nsgtk_toolbar_cast(nsgtk_scaffolding *g) +void nsgtk_toolbar_cast(struct nsgtk_scaffolding *g) { int i; - nsgtk_scaffolding *list = scaf_list; - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) + struct nsgtk_scaffolding *list; + + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { window->buttonlocations[i] = ((nsgtk_scaffolding_button(g, i)->location >= -1) && (nsgtk_scaffolding_button(g, i)->location < PLACEHOLDER_BUTTON)) ? nsgtk_scaffolding_button(g, i)->location : -1; + } + + list = nsgtk_scaffolding_iterate(NULL); while (list) { if (list != g) for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) @@ -1100,7 +1098,7 @@ void nsgtk_toolbar_cast(nsgtk_scaffolding *g) /** * save toolbar settings to file */ -void nsgtk_toolbar_customization_save(nsgtk_scaffolding *g) +void nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g) { int i; FILE *f = fopen(toolbar_indices_file_location, "w"); diff --git a/gtk/toolbar.h b/gtk/toolbar.h index bcad5cd7e..d0af4f9da 100644 --- a/gtk/toolbar.h +++ b/gtk/toolbar.h @@ -23,13 +23,12 @@ #include "gtk/scaffolding.h" -void nsgtk_toolbar_customization_init(nsgtk_scaffolding *g); -void nsgtk_toolbar_init(nsgtk_scaffolding *g); -void nsgtk_toolbar_customization_load(nsgtk_scaffolding *g); -void nsgtk_toolbar_set_physical(nsgtk_scaffolding *g); -void nsgtk_toolbar_connect_all(nsgtk_scaffolding *g); -int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, nsgtk_scaffolding - *g); +void nsgtk_toolbar_customization_init(struct nsgtk_scaffolding *g); +void nsgtk_toolbar_init(struct nsgtk_scaffolding *g); +void nsgtk_toolbar_customization_load(struct nsgtk_scaffolding *g); +void nsgtk_toolbar_set_physical(struct nsgtk_scaffolding *g); +void nsgtk_toolbar_connect_all(struct nsgtk_scaffolding *g); +int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, struct nsgtk_scaffolding *g); #define TOOLPROTO(q) gboolean nsgtk_toolbar_##q##_button_data(\ GtkWidget *widget, GdkDragContext *cont, GtkSelectionData\ @@ -81,8 +80,8 @@ TOOLPROTO(nexttab); TOOLPROTO(prevtab); TOOLPROTO(savewindowsize); TOOLPROTO(toggledebugging); -TOOLPROTO(saveboxtree); -TOOLPROTO(savedomtree); +TOOLPROTO(debugboxtree); +TOOLPROTO(debugdomtree); TOOLPROTO(contents); TOOLPROTO(guide); TOOLPROTO(info); diff --git a/gtk/treeview.c b/gtk/treeview.c index 2a4732a87..fa8bd8f3c 100644 --- a/gtk/treeview.c +++ b/gtk/treeview.c @@ -24,23 +24,26 @@ #include <assert.h> #include <stdio.h> #include <limits.h> - +#include <string.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> +#include "utils/log.h" +#include "utils/utf8.h" +#include "utils/utils.h" #include "desktop/tree.h" #include "desktop/plotters.h" + #include "gtk/compat.h" #include "gtk/gui.h" #include "gtk/plotters.h" #include "gtk/treeview.h" -#include "utils/log.h" -#include "utils/utils.h" struct nsgtk_treeview { GtkWindow *window; GtkScrolledWindow *scrolled; GtkDrawingArea *drawing_area; + GtkIMContext *input_method; bool mouse_pressed; int mouse_pressed_x; int mouse_pressed_y; @@ -52,6 +55,7 @@ struct nsgtk_treeview { void nsgtk_treeview_destroy(struct nsgtk_treeview *tv) { tree_delete(tv->tree); + g_object_unref(tv->input_method); gtk_widget_destroy(GTK_WIDGET(tv->window)); free(tv); } @@ -206,12 +210,14 @@ void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g) { } -gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget, +static gboolean +nsgtk_tree_window_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer g) { struct nsgtk_treeview *tw = g; struct tree *tree = tw->tree; + gtk_im_context_reset(tw->input_method); gtk_widget_grab_focus(GTK_WIDGET(tw->drawing_area)); tw->mouse_pressed = true; @@ -243,7 +249,8 @@ gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget, return TRUE; } -gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget, +static gboolean +nsgtk_tree_window_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer g) { bool shift = event->state & GDK_SHIFT_MASK; @@ -307,7 +314,8 @@ gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget, return TRUE; } -gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget, +static gboolean +nsgtk_tree_window_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer g) { bool shift = event->state & GDK_SHIFT_MASK; @@ -369,7 +377,8 @@ gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget, } -gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event, +static gboolean +nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer g) { struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g; @@ -381,6 +390,9 @@ gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event, GtkAdjustment *scroll = NULL; gdouble hpage, vpage; + if (gtk_im_context_filter_keypress(tw->input_method, event)) + return TRUE; + nskey = gtk_gui_gdkkey_to_nskey(event); if (tree_keypress(tree, nskey) == true) @@ -473,6 +485,32 @@ gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event, return TRUE; } +static gboolean +nsgtk_tree_window_keyrelease_event(GtkWidget *widget, GdkEventKey *event, + gpointer g) +{ + struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g; + + return gtk_im_context_filter_keypress(tw->input_method, event); +} + +static void +nsgtk_tree_window_input_method_commit(GtkIMContext *ctx, + const gchar *str, gpointer data) +{ + struct nsgtk_treeview *tw = (struct nsgtk_treeview *) data; + size_t len = strlen(str), offset = 0; + + while (offset < len) { + uint32_t nskey = utf8_to_ucs4(str + offset, len - offset); + + tree_keypress(tw->tree, nskey); + + offset = utf8_next(str, len, offset); + } +} + + static const struct treeview_table nsgtk_tree_callbacks = { .redraw_request = nsgtk_tree_redraw_request, .resized = nsgtk_tree_resized, @@ -498,6 +536,7 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags, tv->window = window; tv->scrolled = scrolled; tv->drawing_area = drawing_area; + tv->input_method = gtk_im_multicontext_new(); tv->tree = tree_create(flags, &nsgtk_tree_callbacks, tv); tv->mouse_state = 0; tv->mouse_pressed = false; @@ -510,17 +549,31 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags, #define CONNECT(obj, sig, callback, ptr) \ g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) - CONNECT(drawing_area, "button_press_event", + CONNECT(drawing_area, "button-press-event", nsgtk_tree_window_button_press_event, tv); - CONNECT(drawing_area, "button_release_event", + CONNECT(drawing_area, "button-release-event", nsgtk_tree_window_button_release_event, tv); - CONNECT(drawing_area, "motion_notify_event", + CONNECT(drawing_area, "motion-notify-event", nsgtk_tree_window_motion_notify_event, tv); - CONNECT(drawing_area, "key_press_event", + CONNECT(drawing_area, "key-press-event", nsgtk_tree_window_keypress_event, tv); + CONNECT(drawing_area, "key-release-event", + nsgtk_tree_window_keyrelease_event, + tv); + + + /* input method */ + gtk_im_context_set_client_window(tv->input_method, + nsgtk_widget_get_window(GTK_WIDGET(tv->window))); + gtk_im_context_set_use_preedit(tv->input_method, FALSE); + /* input method signals */ + CONNECT(tv->input_method, "commit", + nsgtk_tree_window_input_method_commit, + tv); + return tv; } diff --git a/gtk/treeview.h b/gtk/treeview.h index 12eb18096..ad8180f33 100644 --- a/gtk/treeview.h +++ b/gtk/treeview.h @@ -24,8 +24,6 @@ #ifndef __NSGTK_TREEVIEW_H__ #define __NSGTK_TREEVIEW_H__ -#include "desktop/browser.h" - struct nsgtk_treeview; struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags, @@ -35,16 +33,6 @@ void nsgtk_treeview_destroy(struct nsgtk_treeview *tv); struct tree *nsgtk_treeview_get_tree(struct nsgtk_treeview *tv); -gboolean nsgtk_tree_window_expose_event(GtkWidget *, GdkEventExpose *, - gpointer g); void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g); -gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget, - GdkEventButton *event, gpointer g); -gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget, - GdkEventButton *event, gpointer g); -gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget, - GdkEventMotion *event, gpointer g); -gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event, - gpointer g); #endif /*__NSGTK_TREEVIEW_H__*/ diff --git a/gtk/viewdata.c b/gtk/viewdata.c new file mode 100644 index 000000000..1b5bfb153 --- /dev/null +++ b/gtk/viewdata.c @@ -0,0 +1,988 @@ +/* + * 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 <stdio.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 "utils/filepath.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; +} + +/** + * open a window to dispaly an existing file. + */ +static nserror +window_init_fname(const char *title, + const char *leafname, + const char *filename) +{ + nserror ret; + FILE *f; + char *ndata; + long tell_len; + size_t ndata_len; + + f = fopen(filename, "r"); + if (f == NULL) { + return NSERROR_NOT_FOUND; + } + if (fseek(f, 0, SEEK_END) != 0) { + fclose(f); + return NSERROR_BAD_SIZE; + } + + tell_len = ftell(f); + if (tell_len == -1) { + fclose(f); + return NSERROR_BAD_SIZE; + } + + if (fseek(f, 0, SEEK_SET) != 0) { + fclose(f); + return NSERROR_BAD_SIZE; + } + + ndata = malloc(tell_len); + + ndata_len = fread(ndata, 1, tell_len, f); + + fclose(f); + + ret = window_init(title, leafname, ndata, ndata_len); + + return ret; +} + +/** + * open a new tab from an existing file. + */ +static nserror +tab_init_fname(const char *title, + const char *leafname, + const char *fname) +{ + nsurl *url; + nserror ret; + + /* Open tab on temporary file */ + ret = netsurf_path_to_nsurl(fname, &url); + 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; + } + + return NSERROR_OK; +} + +/** + * create a new tab from data. + */ +static nserror +tab_init(const char *title, + const char *leafname, + char *ndata, + size_t ndata_len) +{ + nserror ret; + gchar *fname; + gint handle; + FILE *f; + + handle = g_file_open_tmp("nsgtkdataXXXXXX", &fname, NULL); + if ((handle == -1) || (fname == NULL)) { + return NSERROR_SAVE_FAILED; + } + close(handle); /* in case it was binary mode */ + + /* save data to temporary 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); + + ret = tab_init_fname(title, leafname, fname); + if (ret == NSERROR_OK) { + free(ndata); + } + + g_free(fname); + + return ret; +} + + +/** + * Build string vector of search path. + * + * ${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/ + * + * \return string vector of search pathnames or NULL on error. + */ +static char** xdg_data_strvec(void) +{ + const char *xdg_data_dirs; + const char *xdg_data_home; + const char *home_dir; + char *xdg_data_path; + int xdg_data_size; + char **svec; + + xdg_data_dirs = getenv("XDG_DATA_DIRS"); + if ((xdg_data_dirs == NULL) || + (*xdg_data_dirs == 0) || + (strlen(xdg_data_dirs) > 4096)) { + xdg_data_dirs = "/usr/local/share/:/usr/share/"; + } + + xdg_data_home = getenv("XDG_DATA_HOME"); + if ((xdg_data_home == NULL) || + (*xdg_data_home == 0) || + (strlen(xdg_data_home) > 4096)) { + /* $XDG_DATA_HOME is empty use $HOME/.local/share */ + + home_dir = getenv("HOME"); + if ((home_dir == NULL) || + (*home_dir == 0) || + (strlen(home_dir) > 4096)) { + xdg_data_path = strdup(xdg_data_dirs); + } else { + xdg_data_size = strlen(home_dir) + + SLEN("/.local/share:") + + strlen(xdg_data_dirs) + 1; + xdg_data_path = malloc(xdg_data_size); + snprintf(xdg_data_path, xdg_data_size , + "%s/.local/share/:%s", + home_dir, xdg_data_dirs); + } + } else { + xdg_data_size = strlen(xdg_data_home) + + strlen(xdg_data_dirs) + 2; + xdg_data_path = malloc(xdg_data_size); + snprintf(xdg_data_path, xdg_data_size , "%s:%s", + xdg_data_home, xdg_data_dirs); + } + + LOG(("%s", xdg_data_path)); + + svec = filepath_path_to_strvec(xdg_data_path); + free(xdg_data_path); + + return svec; +} + +/** + * Search application defaults file for matching mime type. + * + * create filename form path and applications/defaults.list + * + * look for [Default Applications] + * search lines looking like mime/type=Desktop + * + * \param path The base path. + * \param mimetype The mimetype to search for. + * \return The desktop file associated with the mime type or NULL if not found. + */ +static char *xdg_get_default_app(const char *path, const char *mimetype) +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t rd; + int fname_len; + char *fname; + int mimetype_len; + char *ret = NULL; + + fname_len = strlen(path) + SLEN("/applications/defaults.list") + 1; + fname = malloc(fname_len); + snprintf(fname, fname_len, "%s/applications/defaults.list", path); + + LOG(("Checking %s", fname)); + + fp = fopen(fname, "r"); + free(fname); + if (fp == NULL) { + return NULL; + } + + mimetype_len = strlen(mimetype); + while ((rd = getline(&line, &len, fp)) != -1) { + /* line includes line endings if present, remove them */ + while ((line[rd - 1] == '\n') || (line[rd - 1] == '\r')) { + rd--; + } + line[rd] = 0; + + /* look for mimetype */ + if ((rd > mimetype_len) && + (line[mimetype_len] == '=') && + (strncmp(line, mimetype, mimetype_len) == 0)) { + + ret = strdup(line + mimetype_len + 1); + + LOG(("Found line match for %s length %zu\n", mimetype, rd)); + LOG(("Result %s", ret)); + + break; + } + } + + free(line); + fclose(fp); + + return ret; +} + +/** + * Search desktop file for an Exec line. + * + * search path is combined with applications/application.desktop to + * create a filename. + * + * Desktop file format http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html + * + * \todo The parsing of the desktop file is badly incomplete and needs + * improving. For example the handling of the = delimiter is wrong and + * selection from the "Desktop Entry" group is completely absent. + * + */ +static char *xdg_get_exec_cmd(const char *path, const char *desktop) +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t rd; + int fname_len; + char *fname; + char *ret = NULL; + + fname_len = strlen(path) + SLEN("/applications/") + strlen(desktop) + 1; + fname = malloc(fname_len); + snprintf(fname, fname_len, "%s/applications/%s", path, desktop); + + LOG(("Checking %s", fname)); + + fp = fopen(fname, "r"); + free(fname); + if (fp == NULL) { + return NULL; + } + + while ((rd = getline(&line, &len, fp)) != -1) { + /* line includes line endings if present, remove them */ + while ((line[rd - 1] == '\n') || (line[rd - 1] == '\r')) { + rd--; + } + line[rd] = 0; + + /* look for mimetype */ + if ((rd > (ssize_t)SLEN("Exec=")) && + (strncmp(line, "Exec=", SLEN("Exec=")) == 0)) { + + ret = strdup(line + SLEN("Exec=")); + + LOG(("Found Exec length %zu", rd)); + LOG(("Result %s", ret)); + + break; + } + } + + free(line); + fclose(fp); + + return ret; +} + +static char *exec_arg(const char *arg, int len, const char *fname) +{ + char *res = NULL; + + if (*arg == '%') { + arg++; + if ((*arg == 'f') || (*arg == 'F') || + (*arg == 'u') || (*arg == 'U')) { + res = strdup(fname); + } + } else { + res = calloc(1, len + 1); + if (res != NULL) { + memcpy(res, arg, len); + } + } + + return res; +} + +/** + * Build vector for executing app. + */ +static char **build_exec_argv(const char *fname, const char *exec_cmd) +{ + char **argv; + const char *start; /* current arguments start */ + const char *cur; /* current ptr within exec cmd */ + int aidx = 0; /* argv index */ + + argv = calloc(10, sizeof(char *)); + if (argv == NULL) { + return NULL; + } + + cur = exec_cmd; + while (*cur != 0) { + /* skip whitespace */ + while ((*cur != 0) && (*cur == ' ')) { + cur++; + } + if (*cur == 0) { + break; + } + start = cur; + + /* find end of element */ + while ((*cur != 0) && (*cur != ' ')) { + cur++; + } + + argv[aidx] = exec_arg(start, cur - start, fname); + if (argv[aidx] != NULL) { + LOG(("adding \"%s\"", argv[aidx])); + aidx++; + } + } + + /* if no arguments were found there was nothing to execute */ + if (aidx == 0) { + free(argv); + return NULL; + } + + return argv; +} + + +/** + * open an editor from an existing file. + */ +static nserror +editor_init_fname(const char *title, + const char *leafname, + const char *fname) +{ + char **xdg_data_vec; + int veci; + char *def_app_desktop; /* desktop file of default app for mimetype */ + char *exec_cmd; + char **argv; + + /* build string vector of search path */ + xdg_data_vec = xdg_data_strvec(); + + /* find user configured app for opening text/plain */ + veci = 0; + while (xdg_data_vec[veci] != NULL) { + def_app_desktop = xdg_get_default_app(xdg_data_vec[veci], + "text/plain"); + if (def_app_desktop != NULL) { + break; + } + veci++; + } + + if (def_app_desktop == NULL) { + /* no default app */ + filepath_free_strvec(xdg_data_vec); + return NSERROR_NOT_FOUND; + } + + /* find app to execute */ + veci = 0; + while (xdg_data_vec[veci] != NULL) { + exec_cmd = xdg_get_exec_cmd(xdg_data_vec[veci], def_app_desktop); + if (exec_cmd != NULL) { + break; + } + veci++; + } + free(def_app_desktop); + filepath_free_strvec(xdg_data_vec); + + if (exec_cmd == NULL) { + /* no exec entry */ + return NSERROR_NOT_FOUND; + } + + /* build exec vector */ + argv = build_exec_argv(fname, exec_cmd); + free(exec_cmd); + + /* execute target app on saved data */ + if (g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, + NULL, NULL) != TRUE) { + return NSERROR_NOT_FOUND; + } + filepath_free_strvec(argv); + + return NSERROR_OK; +} + +/** + * open an editor with data. + */ +static nserror +editor_init(const char *title, + const char *leafname, + char *ndata, + size_t ndata_len) +{ + + nserror ret; + gchar *fname; + gint handle; + FILE *f; + + handle = g_file_open_tmp("nsgtkdataXXXXXX", &fname, NULL); + if ((handle == -1) || (fname == NULL)) { + return NSERROR_SAVE_FAILED; + } + close(handle); /* in case it was binary mode */ + + /* save data to temporary 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); + + ret = editor_init_fname(title, leafname, fname); + if (ret == NSERROR_OK) { + free(ndata); + } + + g_free(fname); + + return ret; +} + +/* 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; +} + +/* exported interface documented in gtk/viewdata.h */ +nserror +nsgtk_viewfile(const char *title, + const char *leafname, + const char *filename) +{ + nserror ret; + + switch (nsoption_int(developer_view)) { + case 0: + ret = window_init_fname(title, leafname, filename); + break; + + case 1: + ret = tab_init_fname(title, leafname, filename); + break; + + case 2: + ret = editor_init_fname(title, leafname, filename); + break; + + default: + ret = NSERROR_BAD_PARAMETER; + break; + } + + return ret; +} diff --git a/gtk/viewdata.h b/gtk/viewdata.h new file mode 100644 index 000000000..1767b4821 --- /dev/null +++ b/gtk/viewdata.h @@ -0,0 +1,48 @@ +/* + * 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); + +/** + * Display file to a user. + * + * The file is interpreted as 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 leafname The suggested leafname to be used. + * \param filename The filename of the data to be viewed. + */ +nserror nsgtk_viewfile(const char *title, const char *leafname, const char *filename); + +#endif diff --git a/gtk/viewsource.c b/gtk/viewsource.c new file mode 100644 index 000000000..9c28f6927 --- /dev/null +++ b/gtk/viewsource.c @@ -0,0 +1,76 @@ +/* + * 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 <gtk/gtk.h> + +#include "utils/utils.h" +#include "utils/url.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) { + ret = nsgtk_viewdata(title, filename, ndata, ndata_len); + } + + free(filename); + free(title); +} 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 diff --git a/gtk/window.c b/gtk/window.c index 8f449ced2..4d279fb82 100644 --- a/gtk/window.c +++ b/gtk/window.c @@ -26,13 +26,19 @@ #include <gdk/gdkkeysyms.h> #include <gdk-pixbuf/gdk-pixdata.h> +#include "utils/log.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "utils/nsoption.h" #include "content/hlcache.h" #include "gtk/window.h" -#include "desktop/browser_private.h" +#include "gtk/selection.h" +#include "desktop/gui.h" +#include "desktop/browser.h" #include "desktop/mouse.h" -#include "utils/nsoption.h" #include "desktop/searchweb.h" #include "desktop/textinput.h" + #include "gtk/compat.h" #include "gtk/gui.h" #include "gtk/scaffolding.h" @@ -41,8 +47,6 @@ #include "gtk/tabs.h" #include "gtk/bitmap.h" #include "gtk/gdk.h" -#include "utils/log.h" -#include "utils/utils.h" /* helper macro to conenct signals to callbacks */ #define CONNECT(obj, sig, callback, ptr) \ @@ -54,7 +58,7 @@ struct gui_window { /** The gtk scaffold object containing menu, buttons, url bar, [tabs], * drawing area, etc that may contain one or more gui_windows. */ - nsgtk_scaffolding *scaffold; + struct nsgtk_scaffolding *scaffold; /** The 'content' window that is rendered in the gui_window */ struct browser_window *bw; @@ -102,6 +106,9 @@ struct gui_window { /** The icon this window should have */ GdkPixbuf *icon; + /** The input method to use with this window */ + GtkIMContext *input_method; + /** list for cleanup */ struct gui_window *next, *prev; }; @@ -109,7 +116,7 @@ struct gui_window { struct gui_window *window_list = NULL; /**< first entry in win list*/ int temp_open_background = -1; -nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g) +struct nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g) { return g->scaffold; } @@ -152,7 +159,7 @@ struct gui_window *nsgtk_window_iterate(struct gui_window *g) float nsgtk_get_scale_for_gui(struct gui_window *g) { - return g->bw->scale; + return browser_window_get_scale(g->bw); } #if GTK_CHECK_VERSION(3,0,0) @@ -301,7 +308,8 @@ static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, g->mouse.state ^= BROWSER_MOUSE_MOD_2; browser_window_mouse_track(g->bw, g->mouse.state, - event->x / g->bw->scale, event->y / g->bw->scale); + event->x / browser_window_get_scale(g->bw), + event->y / browser_window_get_scale(g->bw)); return TRUE; } @@ -311,12 +319,13 @@ static gboolean nsgtk_window_button_press_event(GtkWidget *widget, { struct gui_window *g = data; + gtk_im_context_reset(g->input_method); gtk_widget_grab_focus(GTK_WIDGET(g->layout)); gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window( g->scaffold)->window)); - g->mouse.pressed_x = event->x / g->bw->scale; - g->mouse.pressed_y = event->y / g->bw->scale; + g->mouse.pressed_x = event->x / browser_window_get_scale(g->bw); + g->mouse.pressed_y = event->y / browser_window_get_scale(g->bw); switch (event->button) { case 1: /* Left button, usually. Pass to core as BUTTON 1. */ @@ -329,8 +338,9 @@ static gboolean nsgtk_window_button_press_event(GtkWidget *widget, case 3: /* Right button, usually. Action button, context menu. */ browser_window_remove_caret(g->bw, true); - nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse.pressed_x, - g->mouse.pressed_y); + nsgtk_scaffolding_context_menu(g->scaffold, + g->mouse.pressed_x, + g->mouse.pressed_y); return TRUE; default: @@ -382,11 +392,12 @@ static gboolean nsgtk_window_button_release_event(GtkWidget *widget, if (g->mouse.state & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) { browser_window_mouse_click(g->bw, g->mouse.state, - event->x / g->bw->scale, - event->y / g->bw->scale); + event->x / browser_window_get_scale(g->bw), + event->y / browser_window_get_scale(g->bw)); } else { - browser_window_mouse_track(g->bw, 0, event->x / g->bw->scale, - event->y / g->bw->scale); + browser_window_mouse_track(g->bw, 0, + event->x / browser_window_get_scale(g->bw), + event->y / browser_window_get_scale(g->bw)); } g->mouse.state = 0; @@ -437,9 +448,9 @@ nsgtk_window_scroll_event(GtkWidget *widget, deltay *= nsgtk_adjustment_get_step_increment(vscroll); if (browser_window_scroll_at_point(g->bw, - event->x / g->bw->scale, - event->y / g->bw->scale, - deltax, deltay) != true) { + event->x / browser_window_get_scale(g->bw), + event->y / browser_window_get_scale(g->bw), + deltax, deltay) != true) { /* core did not handle event so change adjustments */ @@ -485,7 +496,12 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { struct gui_window *g = data; - uint32_t nskey = gtk_gui_gdkkey_to_nskey(event); + uint32_t nskey; + + if (gtk_im_context_filter_keypress(g->input_method, event)) + return TRUE; + + nskey = gtk_gui_gdkkey_to_nskey(event); if (browser_window_key_press(g->bw, nskey)) return TRUE; @@ -593,14 +609,37 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget, return TRUE; } +static gboolean nsgtk_window_keyrelease_event(GtkWidget *widget, + GdkEventKey *event, gpointer data) +{ + struct gui_window *g = data; + + return gtk_im_context_filter_keypress(g->input_method, event); +} + + +static void nsgtk_window_input_method_commit(GtkIMContext *ctx, + const gchar *str, gpointer data) +{ + struct gui_window *g = data; + size_t len = strlen(str), offset = 0; + + while (offset < len) { + uint32_t nskey = utf8_to_ucs4(str + offset, len - offset); + + browser_window_key_press(g->bw, nskey); + + offset = utf8_next(str, len, offset); + } +} + + static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data) { struct gui_window *g = data; - g->bw->reformat_pending = true; - browser_reformat_pending = true; - + browser_window_schedule_reformat(g->bw); return TRUE; } @@ -653,14 +692,30 @@ static void window_destroy(GtkWidget *widget, gpointer data) struct gui_window *gw = data; browser_window_destroy(gw->bw); + + g_object_unref(gw->input_method); } -/* Core interface docuemnted in desktop/gui.h to create a gui_window */ -struct gui_window *gui_create_browser_window(struct browser_window *bw, - struct browser_window *clone, - bool new_tab) + +/** + * Create and open a gtk container (window or tab) for a browsing context. + * + * \param bw The browsing context to create gui_window for. + * \param existing An existing gui_window, may be NULL + * \param flags flags to control the container creation + * \return gui window, or NULL on error + * + * If GW_CREATE_CLONE flag is set existing is non-NULL. + * + * Front end's gui_window must include a reference to the + * browser window passed in the bw param. + */ +static struct gui_window * +gui_window_create(struct browser_window *bw, + struct gui_window *existing, + gui_window_create_flags flags) { - struct gui_window *g; /**< what we're creating to return */ + struct gui_window *g; /* what is being creating to return */ GError* error = NULL; bool tempback; GtkBuilder* xml; @@ -687,16 +742,14 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, g->bw = bw; g->mouse.state = 0; g->current_pointer = GUI_POINTER_DEFAULT; - if (clone != NULL) { - bw->scale = clone->scale; - } else { - bw->scale = (float) nsoption_int(scale) / 100.0; - } /* attach scaffold */ - if (new_tab) { - assert(clone != NULL); - g->scaffold = clone->window->scaffold; + if (flags & GW_CREATE_TAB) { + if (existing != NULL) { + g->scaffold = existing->scaffold; + } else { + g->scaffold = nsgtk_current_scaffolding(); + } } else { /* Now construct and attach a scaffold */ g->scaffold = nsgtk_new_scaffolding(g); @@ -713,6 +766,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout")); g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar")); g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1")); + g->input_method = gtk_im_multicontext_new(); /* add new gui window to global list (push_top) */ @@ -756,6 +810,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, nsgtk_window_button_release_event, g); CONNECT(g->layout, "key-press-event", nsgtk_window_keypress_event, g); + CONNECT(g->layout, "key-release-event", + nsgtk_window_keyrelease_event, g); CONNECT(g->layout, "size-allocate", nsgtk_window_size_allocate_event, g); CONNECT(g->layout, "scroll-event", @@ -772,6 +828,14 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, CONNECT(g->container, "destroy", window_destroy, g); + /* input method */ + gtk_im_context_set_client_window(g->input_method, + nsgtk_layout_get_bin_window(g->layout)); + gtk_im_context_set_use_preedit(g->input_method, FALSE); + /* input method signals */ + CONNECT(g->input_method, "commit", + nsgtk_window_input_method_commit, g); + /* add the tab container to the scaffold notebook */ switch (temp_open_background) { case -1: @@ -799,35 +863,24 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, void nsgtk_reflow_all_windows(void) { for (struct gui_window *g = window_list; g; g = g->next) { - nsgtk_tab_options_changed( - nsgtk_scaffolding_notebook(g->scaffold)); - g->bw->reformat_pending = true; + nsgtk_tab_options_changed(nsgtk_scaffolding_notebook(g->scaffold)); + browser_window_schedule_reformat(g->bw); } - - browser_reformat_pending = true; } /** - * Process pending reformats + * callback from core to reformat a window. */ - -void nsgtk_window_process_reformats(void) +static void nsgtk_window_reformat(struct gui_window *gw) { - struct gui_window *g; GtkAllocation alloc; - browser_reformat_pending = false; - for (g = window_list; g; g = g->next) { - if (!g->bw->reformat_pending) - continue; + if (gw != NULL) { + /** @todo consider gtk_widget_get_allocated_width() */ + nsgtk_widget_get_allocation(GTK_WIDGET(gw->layout), &alloc); - g->bw->reformat_pending = false; - - /* @todo consider gtk_widget_get_allocated_width() */ - nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); - - browser_window_reformat(g->bw, false, alloc.width, alloc.height); + browser_window_reformat(gw->bw, false, alloc.width, alloc.height); } } @@ -837,7 +890,7 @@ void nsgtk_window_destroy_browser(struct gui_window *gw) gtk_widget_destroy(gw->container); } -void gui_window_destroy(struct gui_window *g) +static void gui_window_destroy(struct gui_window *g) { LOG(("gui_window: %p", g)); assert(g != NULL); @@ -860,7 +913,7 @@ void gui_window_destroy(struct gui_window *g) /** * set favicon */ -void gui_window_set_icon(struct gui_window *gw, hlcache_handle *icon) +static void gui_window_set_icon(struct gui_window *gw, hlcache_handle *icon) { struct bitmap *icon_bitmap = NULL; @@ -887,6 +940,20 @@ void gui_window_set_icon(struct gui_window *gw, hlcache_handle *icon) nsgtk_scaffolding_set_icon(gw); } +static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) +{ + GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout); + GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout); + + assert(vadj); + assert(hadj); + + *sy = (int)(gtk_adjustment_get_value(vadj)); + *sx = (int)(gtk_adjustment_get_value(hadj)); + + return true; +} + static void nsgtk_redraw_caret(struct gui_window *g) { int sx, sy; @@ -901,7 +968,7 @@ static void nsgtk_redraw_caret(struct gui_window *g) } -void gui_window_remove_caret(struct gui_window *g) +static void gui_window_remove_caret(struct gui_window *g) { int sx, sy; int oh = g->careth; @@ -918,50 +985,38 @@ void gui_window_remove_caret(struct gui_window *g) } -void gui_window_redraw_window(struct gui_window *g) +static void gui_window_redraw_window(struct gui_window *g) { gtk_widget_queue_draw(GTK_WIDGET(g->layout)); } -void gui_window_update_box(struct gui_window *g, const struct rect *rect) +static void gui_window_update_box(struct gui_window *g, const struct rect *rect) { int sx, sy; - hlcache_handle *c = g->bw->current_content; + float scale; - if (c == NULL) + if (!browser_window_has_content(g->bw)) return; gui_window_get_scroll(g, &sx, &sy); + scale = browser_window_get_scale(g->bw); gtk_widget_queue_draw_area(GTK_WIDGET(g->layout), - rect->x0 * g->bw->scale - sx, - rect->y0 * g->bw->scale - sy, - (rect->x1 - rect->x0) * g->bw->scale, - (rect->y1 - rect->y0) * g->bw->scale); + rect->x0 * scale - sx, + rect->y0 * scale - sy, + (rect->x1 - rect->x0) * scale, + (rect->y1 - rect->y0) * scale); } -void gui_window_set_status(struct gui_window *g, const char *text) +static void gui_window_set_status(struct gui_window *g, const char *text) { assert(g); assert(g->status_bar); gtk_label_set_text(g->status_bar, text); } -bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) -{ - GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout); - GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout); - - assert(vadj); - assert(hadj); - - *sy = (int)(gtk_adjustment_get_value(vadj)); - *sx = (int)(gtk_adjustment_get_value(hadj)); - - return true; -} -void gui_window_set_scroll(struct gui_window *g, int sx, int sy) +static void gui_window_set_scroll(struct gui_window *g, int sx, int sy) { GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout); GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout); @@ -986,21 +1041,13 @@ void gui_window_set_scroll(struct gui_window *g, int sx, int sy) gtk_adjustment_set_value(hadj, x); } -void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, - int x1, int y1) -{ - gui_window_set_scroll(g,x0,y0); -} - - -void gui_window_update_extent(struct gui_window *g) +static void gui_window_update_extent(struct gui_window *g) { - if (!g->bw->current_content) - return; + int w, h; - gtk_layout_set_size(g->layout, - content_get_width(g->bw->current_content) * g->bw->scale, - content_get_height(g->bw->current_content) * g->bw->scale); + if (browser_window_get_extents(g->bw, true, &w, &h) == NSERROR_OK) { + gtk_layout_set_size(g->layout, w, h); + } } static GdkCursor *nsgtk_create_menu_cursor(void) @@ -1014,7 +1061,8 @@ static GdkCursor *nsgtk_create_menu_cursor(void) return cursor; } -void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) +static void gui_window_set_pointer(struct gui_window *g, + gui_pointer_shape shape) { GdkCursor *cursor = NULL; GdkCursorType cursortype; @@ -1098,53 +1146,35 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) nsgdk_cursor_unref(cursor); } -void gui_window_hide_pointer(struct gui_window *g) -{ -} - -void gui_window_place_caret(struct gui_window *g, int x, int y, int height, +static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip) { nsgtk_redraw_caret(g); - g->caretx = x; - g->carety = y + 1; - g->careth = height - 2; - - nsgtk_redraw_caret(g); - - gtk_widget_grab_focus(GTK_WIDGET(g->layout)); -} + y += 1; + height -= 1; -void gui_window_new_content(struct gui_window *g) -{ - -} + if (y < clip->y0) { + height -= clip->y0 - y; + y = clip->y0; + } -bool gui_window_scroll_start(struct gui_window *g) -{ - return true; -} + if (y + height > clip->y1) { + height = clip->y1 - y + 1; + } -bool gui_window_drag_start(struct gui_window *g, gui_drag_type type, - const struct rect *rect) -{ - return true; -} + g->caretx = x; + g->carety = y; + g->careth = height; -void gui_drag_save_object(gui_save_type type, hlcache_handle *c, - struct gui_window *g) -{ + nsgtk_redraw_caret(g); + gtk_widget_grab_focus(GTK_WIDGET(g->layout)); } -void gui_drag_save_selection(struct gui_window *g, const char *selection) -{ - -} -void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, +static void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { GtkAllocation alloc; @@ -1156,9 +1186,75 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, *height = alloc.height; if (scaled) { - *width /= g->bw->scale; - *height /= g->bw->scale; + float scale = browser_window_get_scale(g->bw); + *width /= scale; + *height /= scale; } LOG(("width: %i", *width)); LOG(("height: %i", *height)); } + +static void gui_window_start_selection(struct gui_window *g) +{ + gtk_widget_grab_focus(GTK_WIDGET(g->layout)); +} + +static void +gui_window_file_gadget_open(struct gui_window *g, + hlcache_handle *hl, + struct form_control *gadget) +{ + GtkWidget *dialog; + + dialog = gtk_file_chooser_dialog_new("Select File", + nsgtk_scaffolding_window(g->scaffold), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + LOG(("*** open dialog: %p", dialog)); + + int ret = gtk_dialog_run(GTK_DIALOG(dialog)); + LOG(("*** return value: %d", ret)); + if (ret == GTK_RESPONSE_ACCEPT) { + char *filename; + + filename = gtk_file_chooser_get_filename( + GTK_FILE_CHOOSER(dialog)); + + browser_window_set_gadget_filename(g->bw, gadget, filename); + + g_free(filename); + } + + gtk_widget_destroy(dialog); +} + +static struct gui_window_table window_table = { + .create = gui_window_create, + .destroy = gui_window_destroy, + .redraw = gui_window_redraw_window, + .update = gui_window_update_box, + .get_scroll = gui_window_get_scroll, + .set_scroll = gui_window_set_scroll, + .get_dimensions = gui_window_get_dimensions, + .update_extent = gui_window_update_extent, + .reformat = nsgtk_window_reformat, + + .set_icon = gui_window_set_icon, + .set_status = gui_window_set_status, + .set_pointer = gui_window_set_pointer, + .place_caret = gui_window_place_caret, + .remove_caret = gui_window_remove_caret, + .file_gadget_open = gui_window_file_gadget_open, + .start_selection = gui_window_start_selection, + + /* from scaffold */ + .set_title = gui_window_set_title, + .set_url = gui_window_set_url, + .start_throbber = gui_window_start_throbber, + .stop_throbber = gui_window_stop_throbber, +}; + +struct gui_window_table *nsgtk_window_table = &window_table; diff --git a/gtk/window.h b/gtk/window.h index 2def42dd5..c604bf3f7 100644 --- a/gtk/window.h +++ b/gtk/window.h @@ -19,10 +19,9 @@ #ifndef NETSURF_GTK_WINDOW_H #define NETSURF_GTK_WINDOW_H 1 -#include "desktop/gui.h" -#include "desktop/browser.h" #include "gtk/scaffolding.h" +extern struct gui_window_table *nsgtk_window_table; typedef enum nsgtk_window_signals { NSGTK_WINDOW_SIGNAL_CLICK, @@ -33,12 +32,10 @@ typedef enum nsgtk_window_signals { extern struct gui_window *window_list; extern int temp_open_background; - struct browser_window *nsgtk_get_browser_window(struct gui_window *g); -nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g); +struct nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g); GdkPixbuf *nsgtk_get_icon(struct gui_window *gw); void nsgtk_reflow_all_windows(void); -void nsgtk_window_process_reformats(void); float nsgtk_get_scale_for_gui(struct gui_window *g); int nsgtk_gui_window_update_targets(struct gui_window *g); void nsgtk_window_destroy_browser(struct gui_window *g); @@ -48,5 +45,4 @@ struct gui_window *nsgtk_window_iterate(struct gui_window *g); GtkWidget *nsgtk_window_get_tab(struct gui_window *g); void nsgtk_window_set_tab(struct gui_window *g, GtkWidget *w); - #endif /* NETSURF_GTK_WINDOW_H */ |