NetSurf
global_history.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 John Mark Bell <jmb@netsurf-browser.org>
3 * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * Implementation of GTK global history manager.
23 */
24
25#include <stdint.h>
26#include <stdlib.h>
27#include <gtk/gtk.h>
28
29#include "utils/log.h"
30#include "netsurf/keypress.h"
31#include "netsurf/plotters.h"
33
34#include "gtk/compat.h"
35#include "gtk/plotters.h"
36#include "gtk/resources.h"
37#include "gtk/corewindow.h"
38#include "gtk/global_history.h"
39
42 GtkBuilder *builder;
43 GtkWindow *wnd;
44};
45
47
48#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
49 GtkMenuItem *widget, gpointer g)
50#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) }
51#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \
52 gpointer g)
53
54struct menu_events {
55 const char *widget;
56 GCallback handler;
57};
58
59/* file menu*/
60MENUPROTO(export);
61
62/* edit menu */
63MENUPROTO(delete_selected);
64MENUPROTO(delete_all);
65MENUPROTO(select_all);
66MENUPROTO(clear_selection);
67
68/* view menu*/
69MENUPROTO(expand_all);
70MENUPROTO(expand_directories);
71MENUPROTO(expand_addresses);
72MENUPROTO(collapse_all);
73MENUPROTO(collapse_directories);
74MENUPROTO(collapse_addresses);
75
76MENUPROTO(launch);
77
78static struct menu_events menu_events[] = {
79
80 /* file menu*/
81 MENUEVENT(export),
82
83 /* edit menu */
84 MENUEVENT(delete_selected),
85 MENUEVENT(delete_all),
86 MENUEVENT(select_all),
87 MENUEVENT(clear_selection),
88
89 /* view menu*/
90 MENUEVENT(expand_all),
91 MENUEVENT(expand_directories),
92 MENUEVENT(expand_addresses),
93 MENUEVENT(collapse_all),
94 MENUEVENT(collapse_directories),
95 MENUEVENT(collapse_addresses),
96
97 MENUEVENT(launch),
98 {NULL, NULL}
99};
100
101/* edit menu */
102MENUHANDLER(delete_selected)
103{
105 return TRUE;
106}
107
108MENUHANDLER(delete_all)
109{
114 return TRUE;
115}
116
117MENUHANDLER(select_all)
118{
122 return TRUE;
123}
124
125MENUHANDLER(clear_selection)
126{
130 return TRUE;
131}
132
133/* view menu*/
134MENUHANDLER(expand_all)
135{
137 return TRUE;
138}
139
140MENUHANDLER(expand_directories)
141{
143 return TRUE;
144}
145
146MENUHANDLER(expand_addresses)
147{
149 return TRUE;
150}
151
152MENUHANDLER(collapse_all)
153{
155 return TRUE;
156}
157
158MENUHANDLER(collapse_directories)
159{
161 return TRUE;
162}
163
164MENUHANDLER(collapse_addresses)
165{
167 return TRUE;
168}
169
171{
173 return TRUE;
174}
175
176/* file menu */
178{
179 struct nsgtk_global_history_window *ghwin;
180 GtkWidget *save_dialog;
181
182 ghwin = (struct nsgtk_global_history_window *)g;
183
184 save_dialog = gtk_file_chooser_dialog_new("Save File",
185 ghwin->wnd,
186 GTK_FILE_CHOOSER_ACTION_SAVE,
187 NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
188 NSGTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
189 NULL);
190
191 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog),
192 getenv("HOME") ? getenv("HOME") : "/");
193
194 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog),
195 "history.html");
196
197 if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) {
198 gchar *filename = gtk_file_chooser_get_filename(
199 GTK_FILE_CHOOSER(save_dialog));
200
201 global_history_export(filename, NULL);
202 g_free(filename);
203 }
204
205 gtk_widget_destroy(save_dialog);
206
207 return TRUE;
208}
209
210/**
211 * Connects menu events in the global history window.
212 */
213static void
215{
216 struct menu_events *event = menu_events;
217 GtkWidget *w;
218
219 while (event->widget != NULL) {
220 w = GTK_WIDGET(gtk_builder_get_object(ghwin->builder,
221 event->widget));
222 if (w == NULL) {
223 NSLOG(netsurf, INFO,
224 "Unable to connect menu widget ""%s""",
225 event->widget);
226 } else {
227 g_signal_connect(G_OBJECT(w),
228 "activate",
229 event->handler,
230 ghwin);
231 }
232 event++;
233 }
234}
235
236
237/**
238 * callback for mouse action on global history window
239 *
240 * \param nsgtk_cw The nsgtk core window structure.
241 * \param mouse_state netsurf mouse state on event
242 * \param x location of event
243 * \param y location of event
244 * \return NSERROR_OK on success otherwise apropriate error code
245 */
246static nserror
248 browser_mouse_state mouse_state,
249 int x, int y)
250{
251 global_history_mouse_action(mouse_state, x, y);
252
253 return NSERROR_OK;
254}
255
256
257/**
258 * callback for keypress on global history window
259 *
260 * \param nsgtk_cw The nsgtk core window structure.
261 * \param nskey The netsurf key code
262 * \return NSERROR_OK on success otherwise apropriate error code
263 */
264static nserror
265nsgtk_global_history_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
266{
267 if (global_history_keypress(nskey)) {
268 return NSERROR_OK;
269 }
271}
272
273
274/**
275 * callback on draw event for global history window
276 *
277 * \param nsgtk_cw The nsgtk core window structure.
278 * \param r The rectangle of the window that needs updating.
279 * \return NSERROR_OK on success otherwise apropriate error code
280 */
281static nserror
283{
284 struct redraw_context ctx = {
285 .interactive = true,
286 .background_images = true,
287 .plot = &nsgtk_plotters
288 };
289
290 global_history_redraw(0, 0, r, &ctx);
291
292 return NSERROR_OK;
293}
294
295/**
296 * Creates the window for the global history tree.
297 *
298 * \return NSERROR_OK on success else appropriate error code on faliure.
299 */
301{
302 struct nsgtk_global_history_window *ncwin;
303 nserror res;
304
305 if (global_history_window != NULL) {
306 return NSERROR_OK;
307 }
308
309 ncwin = calloc(1, sizeof(*ncwin));
310 if (ncwin == NULL) {
311 return NSERROR_NOMEM;
312 }
313
314 res = nsgtk_builder_new_from_resname("globalhistory", &ncwin->builder);
315 if (res != NSERROR_OK) {
316 NSLOG(netsurf, INFO, "History UI builder init failed");
317 free(ncwin);
318 return res;
319 }
320
321 gtk_builder_connect_signals(ncwin->builder, NULL);
322
323 ncwin->wnd = GTK_WINDOW(gtk_builder_get_object(ncwin->builder,
324 "wndHistory"));
325
326 ncwin->core.scrolled = GTK_SCROLLED_WINDOW(
327 gtk_builder_get_object(ncwin->builder,
328 "globalHistoryScrolled"));
329
330 ncwin->core.drawing_area = GTK_DRAWING_AREA(
331 gtk_builder_get_object(ncwin->builder,
332 "globalHistoryDrawingArea"));
333
334 /* make the delete event hide the window */
335 g_signal_connect(G_OBJECT(ncwin->wnd),
336 "delete_event",
337 G_CALLBACK(gtk_widget_hide_on_delete),
338 NULL);
339
341
345
346 res = nsgtk_corewindow_init(&ncwin->core);
347 if (res != NSERROR_OK) {
348 free(ncwin);
349 return res;
350 }
351
352 res = global_history_init((struct core_window *)ncwin);
353 if (res != NSERROR_OK) {
354 free(ncwin);
355 return res;
356 }
357
358 /* memoise window so it can be represented when necessary
359 * instead of recreating every time.
360 */
361 global_history_window = ncwin;
362
363 return NSERROR_OK;
364}
365
366
367/* exported function documented gtk/history.h */
369{
370 nserror res;
371
373 if (res == NSERROR_OK) {
374 gtk_window_present(global_history_window->wnd);
375 }
376 return res;
377}
378
379
380/* exported function documented gtk/history.h */
382{
383 nserror res;
384
385 if (global_history_window == NULL) {
386 return NSERROR_OK;
387 }
388
389 res = global_history_fini();
390 if (res == NSERROR_OK) {
392 gtk_widget_destroy(GTK_WIDGET(global_history_window->wnd));
393 g_object_unref(G_OBJECT(global_history_window->builder));
396 }
397
398 return res;
399
400}
401
402
403
Compatibility functions for older GTK versions (interface)
#define NSGTK_STOCK_SAVE
Definition: compat.h:61
#define NSGTK_STOCK_CANCEL
Definition: compat.h:55
nserror global_history_init(void *core_window_handle)
Initialise the global history.
nserror global_history_expand(bool only_folders)
Expand the treeview's nodes.
nserror global_history_fini(void)
Finalise the global history.
void global_history_redraw(int x, int y, struct rect *clip, const struct redraw_context *ctx)
Redraw the global history.
nserror global_history_export(const char *path, const char *title)
Save global history to file (html)
nserror global_history_contract(bool all)
Contract the treeview's nodes.
bool global_history_keypress(uint32_t key)
Key press handling.
void global_history_mouse_action(browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOT_IMPLEMENTED
Functionality is not implemented.
Definition: errors.h:61
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
#define MENUHANDLER(x)
nserror nsgtk_global_history_present(void)
make the global history window visible.
nserror nsgtk_global_history_destroy(void)
Destroys the global history window and performs any other necessary cleanup actions.
static struct nsgtk_global_history_window * global_history_window
static nserror nsgtk_global_history_init(void)
Creates the window for the global history tree.
#define MENUEVENT(x)
static struct menu_events menu_events[]
static nserror nsgtk_global_history_mouse(struct nsgtk_corewindow *nsgtk_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse action on global history window
#define MENUPROTO(x)
static void nsgtk_global_history_init_menu(struct nsgtk_global_history_window *ghwin)
Connects menu events in the global history window.
static nserror nsgtk_global_history_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
callback on draw event for global history window
static nserror nsgtk_global_history_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
callback for keypress on global history window
Interface to GTK global history manager.
Target independent plotting GTK+ interface.
nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw)
initialise elements of gtk core window.
Definition: corewindow.c:733
nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw)
finalise elements of gtk core window.
Definition: corewindow.c:786
const struct plotter_table nsgtk_plotters
GTK plotter table.
Definition: plotters.c:647
browser_mouse_state
Mouse state: 1 is primary mouse button.
Definition: mouse.h:52
Target independent plotting interface.
Interface to key press operations.
@ NS_KEY_CR
Definition: keypress.h:40
@ NS_KEY_SELECT_ALL
Definition: keypress.h:32
@ NS_KEY_CLEAR_SELECTION
Definition: keypress.h:45
@ NS_KEY_DELETE_LEFT
Definition: keypress.h:35
@ NS_KEY_ESCAPE
Definition: keypress.h:47
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
nserror nsgtk_builder_new_from_resname(const char *resname, GtkBuilder **builder_out)
Create gtk builder object for the named ui resource.
Definition: resources.c:526
Interface to gtk builtin resource handling.
GCallback handler
Definition: cookies.c:54
const char * widget
nsgtk core window state
Definition: corewindow.h:41
nserror(* key)(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
callback for keypress on nsgtk core window
Definition: corewindow.h:76
nserror(* draw)(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
callback to draw on drawable area of nsgtk core window
Definition: corewindow.h:65
GtkScrolledWindow * scrolled
scrollable area drawing area is within
Definition: corewindow.h:46
nserror(* mouse)(struct nsgtk_corewindow *nsgtk_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on nsgtk core window
Definition: corewindow.h:87
GtkDrawingArea * drawing_area
GTK drawable widget.
Definition: corewindow.h:44
struct nsgtk_corewindow core
Rectangle coordinates.
Definition: types.h:40
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59