From 8547452232e1cc7664fe3af7cbcfc4cead9d7d92 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 6 Aug 2016 17:08:21 +0100 Subject: convert GTK hotlist to use GTK core window --- frontends/gtk/global_history.c | 4 +- frontends/gtk/gui.c | 12 +- frontends/gtk/hotlist.c | 335 +++++++++++++++++++++++++++++------------ frontends/gtk/hotlist.h | 21 +-- frontends/gtk/scaffolding.c | 9 +- 5 files changed, 259 insertions(+), 122 deletions(-) (limited to 'frontends') diff --git a/frontends/gtk/global_history.c b/frontends/gtk/global_history.c index df6fe06e7..b41d06ef6 100644 --- a/frontends/gtk/global_history.c +++ b/frontends/gtk/global_history.c @@ -1,6 +1,6 @@ /* - * Copyright 2006 Rob Kendrick - * Copyright 2009 Paul Blokus + * Copyright 2010 John Mark Bell + * Copyright 2016 Vincent Sanders * * This file is part of NetSurf, http://www.netsurf-browser.org/ * diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c index 8d0bb75d7..61560ddab 100644 --- a/frontends/gtk/gui.c +++ b/frontends/gtk/gui.c @@ -307,12 +307,6 @@ static nserror nsgtk_init(int argc, char** argv, char **respath) return error; } - error = nsgtk_hotlist_init(); - if (error != NSERROR_OK) { - LOG("Unable to initialise hotlist window."); - return error; - } - /* If there is a url specified on the command line use it */ if (argc > 1) { struct stat fs; @@ -449,7 +443,11 @@ static void gui_quit(void) messages_get_errorcode(res)); } - nsgtk_hotlist_destroy(); + res = nsgtk_hotlist_destroy(); + if (res != NSERROR_OK) { + LOG("Error finalising hotlist viewer: %s", + messages_get_errorcode(res)); + } free(nsgtk_config_home); diff --git a/frontends/gtk/hotlist.c b/frontends/gtk/hotlist.c index fdc5be3b2..2d0641ff2 100644 --- a/frontends/gtk/hotlist.c +++ b/frontends/gtk/hotlist.c @@ -1,5 +1,6 @@ /* - * Copyright 2009 Paul Blokus + * Copyright 2010 John Mark Bell + * Copyright 2016 Vincent Sanders * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -16,25 +17,40 @@ * along with this program. If not, see . */ +/** + * \file + * Implementation of GTK bookmark (hotlist) manager. + */ + +#include #include #include #include "utils/log.h" #include "utils/nsoption.h" #include "netsurf/keypress.h" +#include "netsurf/plotters.h" #include "desktop/hotlist.h" -#include "desktop/tree.h" +#include "desktop/treeview.h" -#include "gtk/plotters.h" -#include "gtk/scaffolding.h" -#include "gtk/treeview.h" #include "gtk/compat.h" +#include "gtk/plotters.h" #include "gtk/resources.h" +#include "gtk/corewindow.h" #include "gtk/hotlist.h" +struct nsgtk_hotlist_window { + struct nsgtk_corewindow core; + GtkBuilder *builder; + GtkWindow *wnd; + const char *path; /**< path to users bookmarks */ +}; + +static struct nsgtk_hotlist_window *hotlist_window = NULL; + #define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \ GtkMenuItem *widget, gpointer g) -#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) } +#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) } #define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \ gpointer g) @@ -58,7 +74,7 @@ MENUPROTO(clear_selection); /* view menu*/ MENUPROTO(expand_all); MENUPROTO(expand_directories); -MENUPROTO(expand_addresses); +MENUPROTO(expand_addresses); MENUPROTO(collapse_all); MENUPROTO(collapse_directories); MENUPROTO(collapse_addresses); @@ -66,135 +82,61 @@ MENUPROTO(collapse_addresses); MENUPROTO(launch); static struct menu_events menu_events[] = { - + /* file menu*/ MENUEVENT(export), MENUEVENT(new_folder), MENUEVENT(new_entry), - + /* edit menu */ MENUEVENT(edit_selected), MENUEVENT(delete_selected), MENUEVENT(select_all), MENUEVENT(clear_selection), - + /* view menu*/ MENUEVENT(expand_all), MENUEVENT(expand_directories), - MENUEVENT(expand_addresses), + MENUEVENT(expand_addresses), MENUEVENT(collapse_all), MENUEVENT(collapse_directories), MENUEVENT(collapse_addresses), - - MENUEVENT(launch), - {NULL, NULL} -}; - -static struct nsgtk_treeview *hotlist_treeview; -static GtkBuilder *hotlist_builder; -GtkWindow *wndHotlist; - -/** - * Connects menu events in the hotlist window. - */ -static void nsgtk_hotlist_init_menu(void) -{ - struct menu_events *event = menu_events; - GtkWidget *w; - - while (event->widget != NULL) { - w = GTK_WIDGET(gtk_builder_get_object(hotlist_builder, event->widget)); - if (w == NULL) { - LOG("Unable to connect menu widget ""%s""", event->widget); } else { - g_signal_connect(G_OBJECT(w), "activate", event->handler, hotlist_treeview); - } - event++; - } -} - -/* exported interface docuemnted in gtk/hotlist.h */ -nserror nsgtk_hotlist_init(void) -{ - GtkWindow *window; - GtkScrolledWindow *scrolled; - GtkDrawingArea *drawing_area; - nserror res; - - res = nsgtk_builder_new_from_resname("hotlist", &hotlist_builder); - if (res != NSERROR_OK) { - LOG("Cookie UI builder init failed"); - return res; - } - - gtk_builder_connect_signals(hotlist_builder, NULL); - - wndHotlist = GTK_WINDOW(gtk_builder_get_object(hotlist_builder, "wndHotlist")); - window = wndHotlist; - - scrolled = GTK_SCROLLED_WINDOW(gtk_builder_get_object(hotlist_builder, - "hotlistScrolled")); - - drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(hotlist_builder, - "hotlistDrawingArea")); - - - tree_hotlist_path = nsoption_charp(hotlist_path); - hotlist_treeview = nsgtk_treeview_create(TREE_HOTLIST, window, - scrolled, drawing_area, NULL); - - if (hotlist_treeview == NULL) { - return NSERROR_INIT_FAILED; - } - -#define CONNECT(obj, sig, callback, ptr) \ - g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) - - CONNECT(window, "delete_event", gtk_widget_hide_on_delete, NULL); - CONNECT(window, "hide", nsgtk_tree_window_hide, hotlist_treeview); - - nsgtk_hotlist_init_menu(); - - return NSERROR_OK; -} - - + MENUEVENT(launch), -/** - * Destroys the hotlist window and performs any other necessary cleanup actions. - */ -void nsgtk_hotlist_destroy(void) -{ - /** \todo what about hotlist_builder? */ - nsgtk_treeview_destroy(hotlist_treeview); -} + {NULL, NULL} +}; /* file menu*/ MENUHANDLER(export) { + struct nsgtk_hotlist_window *hlwin; GtkWidget *save_dialog; + + hlwin = (struct nsgtk_hotlist_window *)g; + save_dialog = gtk_file_chooser_dialog_new("Save File", - wndHotlist, + hlwin->wnd, GTK_FILE_CHOOSER_ACTION_SAVE, NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NSGTK_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), "hotlist.html"); - + if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(save_dialog)); - - hotlist_export(filename, NULL); + + hotlist_export(filename, NULL); g_free(filename); } - + gtk_widget_destroy(save_dialog); return TRUE; @@ -279,3 +221,198 @@ MENUHANDLER(launch) hotlist_keypress(NS_KEY_CR); return TRUE; } + + +/** + * Connects menu events in the hotlist window. + */ +static void nsgtk_hotlist_init_menu(struct nsgtk_hotlist_window *hlwin) +{ + struct menu_events *event = menu_events; + GtkWidget *w; + + while (event->widget != NULL) { + w = GTK_WIDGET(gtk_builder_get_object(hlwin->builder, + event->widget)); + if (w == NULL) { + LOG("Unable to connect menu widget ""%s""", + event->widget); + } else { + g_signal_connect(G_OBJECT(w), + "activate", + event->handler, + hlwin); + } + event++; + } +} + + +/** + * callback for mouse action on hotlist window + * + * \param nsgtk_cw The nsgtk core window structure. + * \param mouse_state netsurf mouse state on event + * \param x location of event + * \param y location of event + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +nsgtk_hotlist_mouse(struct nsgtk_corewindow *nsgtk_cw, + browser_mouse_state mouse_state, + int x, int y) +{ + hotlist_mouse_action(mouse_state, x, y); + + return NSERROR_OK; +} + +/** + * callback for keypress on hotlist window + * + * \param nsgtk_cw The nsgtk core window structure. + * \param nskey The netsurf key code + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +nsgtk_hotlist_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey) +{ + if (hotlist_keypress(nskey)) { + return NSERROR_OK; + } + return NSERROR_NOT_IMPLEMENTED; +} + +/** + * callback on draw event for hotlist window + * + * \param nsgtk_cw The nsgtk core window structure. + * \param r The rectangle of the window that needs updating. + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +nsgtk_hotlist_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r) +{ + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &nsgtk_plotters + }; + + hotlist_redraw(0, 0, r, &ctx); + + return NSERROR_OK; +} + +/** + * Creates the window for the hotlist tree. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +static nserror nsgtk_hotlist_init(void) +{ + struct nsgtk_hotlist_window *ncwin; + nserror res; + + if (hotlist_window != NULL) { + return NSERROR_OK; + } + + res = treeview_init(0); + if (res != NSERROR_OK) { + return res; + } + + ncwin = malloc(sizeof(struct nsgtk_hotlist_window)); + if (ncwin == NULL) { + return NSERROR_NOMEM; + } + + res = nsgtk_builder_new_from_resname("hotlist", &ncwin->builder); + if (res != NSERROR_OK) { + LOG("Hotlist UI builder init failed"); + free(ncwin); + return res; + } + + gtk_builder_connect_signals(ncwin->builder, NULL); + + ncwin->wnd = GTK_WINDOW(gtk_builder_get_object(ncwin->builder, + "wndHotlist")); + + ncwin->core.scrolled = GTK_SCROLLED_WINDOW( + gtk_builder_get_object(ncwin->builder, "hotlistScrolled")); + + ncwin->core.drawing_area = GTK_DRAWING_AREA( + gtk_builder_get_object(ncwin->builder, "hotlistDrawingArea")); + + /* make the delete event hide the window */ + g_signal_connect(G_OBJECT(ncwin->wnd), + "delete_event", + G_CALLBACK(gtk_widget_hide_on_delete), + NULL); + + nsgtk_hotlist_init_menu(ncwin); + + ncwin->core.draw = nsgtk_hotlist_draw; + ncwin->core.key = nsgtk_hotlist_key; + ncwin->core.mouse = nsgtk_hotlist_mouse; + + res = nsgtk_corewindow_init(&ncwin->core); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + ncwin->path = nsoption_charp(hotlist_path); + + res = hotlist_init(ncwin->core.cb_table, + (struct core_window *)ncwin, + ncwin->path); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + /* memoise window so it can be represented when necessary + * instead of recreating every time. + */ + hotlist_window = ncwin; + + return NSERROR_OK; +} + + +/* exported function documented gtk/hotlist.h */ +nserror nsgtk_hotlist_present(void) +{ + nserror res; + + res = nsgtk_hotlist_init(); + if (res == NSERROR_OK) { + gtk_window_present(hotlist_window->wnd); + } + return res; +} + + +/* exported function documented gtk/hotlist.h */ +nserror nsgtk_hotlist_destroy(void) +{ + nserror res; + + if (hotlist_window == NULL) { + return NSERROR_OK; + } + + res = hotlist_fini(hotlist_window->path); + if (res == NSERROR_OK) { + res = nsgtk_corewindow_fini(&hotlist_window->core); + gtk_widget_destroy(GTK_WIDGET(hotlist_window->wnd)); + g_object_unref(G_OBJECT(hotlist_window->builder)); + free(hotlist_window); + hotlist_window = NULL; + } + + return res; +} diff --git a/frontends/gtk/hotlist.h b/frontends/gtk/hotlist.h index 01e5a86c5..3170027cd 100644 --- a/frontends/gtk/hotlist.h +++ b/frontends/gtk/hotlist.h @@ -16,25 +16,26 @@ * along with this program. If not, see . */ -/** \file - * GTK hotlist (interface). +/** + * \file + * Interface to GTK bookmarks (hotlist). */ #ifndef __NSGTK_HOTLIST_H__ #define __NSGTK_HOTLIST_H__ -#include - -extern GtkWindow *wndHotlist; - /** - * Initialise the gtk specific hotlist (bookmarks) display. + * make the hotlist window visible. * * \return NSERROR_OK on success else appropriate error code on faliure. */ -nserror nsgtk_hotlist_init(void); - +nserror nsgtk_hotlist_present(void); -void nsgtk_hotlist_destroy(void); +/** + * Free any resources allocated for the hotlist window. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +nserror nsgtk_hotlist_destroy(void); #endif /* __NSGTK_HOTLIST_H__ */ diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c index cdf238bb5..bbc568e15 100644 --- a/frontends/gtk/scaffolding.c +++ b/frontends/gtk/scaffolding.c @@ -1516,10 +1516,11 @@ MULTIHANDLER(addbookmarks) MULTIHANDLER(showbookmarks) { - gtk_widget_show(GTK_WIDGET(wndHotlist)); - gdk_window_raise(nsgtk_widget_get_window(GTK_WIDGET(wndHotlist))); - gtk_window_set_focus(wndHotlist, NULL); - + nserror res; + res = nsgtk_hotlist_present(); + if (res != NSERROR_OK) { + LOG("Unable to initialise bookmark window."); + } return TRUE; } -- cgit v1.2.3