NetSurf
toolbar.c
Go to the documentation of this file.
1/*
2 * Copyright 2019 Vincent Sanders <vince@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * implementation of toolbar to control browsing context
22 */
23
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27#include <errno.h>
28#include <gtk/gtk.h>
29
30#include "utils/log.h"
31#include "utils/messages.h"
32#include "utils/nsoption.h"
33#include "utils/file.h"
34#include "utils/nsurl.h"
35#include "utils/corestrings.h"
37#include "desktop/searchweb.h"
38#include "desktop/search.h"
40#include "desktop/save_text.h"
41#include "desktop/print.h"
42#include "desktop/hotlist.h"
43#include "netsurf/content.h"
45#include "netsurf/keypress.h"
46
47#include "gtk/toolbar_items.h"
48#include "gtk/completion.h"
49#include "gtk/gui.h"
50#include "gtk/warn.h"
51#include "gtk/search.h"
52#include "gtk/throbber.h"
53#include "gtk/scaffolding.h"
54#include "gtk/window.h"
55#include "gtk/compat.h"
56#include "gtk/resources.h"
57#include "gtk/schedule.h"
58#include "gtk/local_history.h"
59#include "gtk/global_history.h"
60#include "gtk/viewsource.h"
61#include "gtk/download.h"
62#include "gtk/viewdata.h"
63#include "gtk/tabs.h"
64#include "gtk/print.h"
65#include "gtk/layout_pango.h"
66#include "gtk/preferences.h"
67#include "gtk/hotlist.h"
68#include "gtk/cookies.h"
69#include "gtk/about.h"
70#include "gtk/gdk.h"
71#include "gtk/bitmap.h"
72#include "gtk/page_info.h"
73#include "gtk/toolbar.h"
74
75/**
76 * button location indicating button is not to be shown
77 */
78#define INACTIVE_LOCATION (-1)
79
80/**
81 * time (in ms) between throbber animation frame updates
82 */
83#define THROBBER_FRAME_TIME (100)
84
85/**
86 * the minimum number of columns in the tool store
87 */
88#define NSGTK_MIN_STORE_COLUMNS 4
89
90/**
91 * the 'standard' width of a button that makes sufficient of its label visible
92 */
93#define NSGTK_BUTTON_WIDTH 120
94
95/**
96 * the 'standard' height of a button that fits as many toolbars as
97 * possible into the store
98 */
99#define NSGTK_BUTTON_HEIGHT 70
100
101/**
102 * the 'normal' width of the websearch bar
103 */
104#define NSGTK_WEBSEARCH_WIDTH 150
105
106/**
107 * toolbar item context
108 */
110
111 /**
112 * GTK widget in the toolbar
113 */
114 GtkToolItem *button;
115
116 /**
117 * location index in toolbar
118 */
120
121 /**
122 * if the item is currently sensitive in the toolbar
123 */
125
126 /**
127 * textural name used in serialising items
128 */
129 const char *name;
130
131 /**
132 * button clicked on toolbar handler
133 */
134 gboolean (*clicked)(GtkWidget *widget, gpointer data);
135
136 /**
137 * handler when dragging from customisation toolbox to toolbar
138 */
139 void *dataplus;
140
141 /**
142 * handler when dragging from toolbar to customisation toolbox
143 */
145};
146
147/**
148 * Location focus state machine
149 *
150 * 1. If we don't care, we're in LFS_IDLE
151 * 2. When we create a new toolbar, we can put it into
152 * LFS_WANT which means that we want the url bar to focus
153 * 3. When we start throbbing if we're in LFS_WANT we move to LFS_THROB
154 * 4. When we stop throbbing, if we're in LFS_THROB we move to LFS_LAST
155 *
156 * While not in LFS_IDLE, if the url bar is updated and we previously had it
157 * fully selected then we reselect it all. If we're in LFS_LAST we move to
158 * LFS_IDLE at that point.
159 */
160typedef enum {
161 LFS_IDLE, /**< Nothing to do */
162 LFS_WANT, /**< Want focus, will apply */
163 LFS_THROB, /**< Want focus, we have started throbbing */
164 LFS_LAST, /**< Last chance for a focus update */
166
167/**
168 * control toolbar context
169 */
171 /** gtk toolbar widget */
172 GtkToolbar *widget;
173
174 /* toolbar size allocation context */
179
180 /**
181 * Toolbar item contexts
182 */
184
185 /**
186 * Current frame of throbber animation
187 */
189
190 /**
191 * Web search widget
192 */
193 GtkWidget *webSearchEntry;
194
195 /**
196 * callback to obtain a browser window for navigation
197 */
198 struct browser_window *(*get_bw)(void *ctx);
199
200 /**
201 * context passed to get_bw function
202 */
203 void *get_ctx;
204
205 /**
206 * Location focus state machine, current state
207 */
209};
210
211
212/**
213 * toolbar cusomisation context
214 */
216 /**
217 * first entry is a toolbar widget so a customisation widget
218 * can be cast to toolbar and back.
219 */
221
222 /**
223 * The top level container (tabBox)
224 */
225 GtkWidget *container;
226
227 /**
228 * The vertical box into which the available tools are shown
229 */
230 GtkBox *toolbox;
231
232 /**
233 * widget handles for items in the customisation toolbox area
234 */
236
237 /**
238 * which item is being dragged
239 */
240 int dragitem; /* currentbutton */
241 /**
242 * true if item being dragged onto toolbar, false if from toolbar
243 */
244 bool dragfrom; /*fromstore */
245
246};
247
248
249/* forward declaration */
251 struct nsgtk_toolbar_item *item_out);
252
253
254/**
255 * returns a string without its underscores
256 *
257 * \param s The string to change.
258 * \param replacespace true to insert a space where there was an underscore
259 * \return The altered string
260 */
261static char *remove_underscores(const char *s, bool replacespace)
262{
263 size_t i, ii, len;
264 char *ret;
265 len = strlen(s);
266 ret = malloc(len + 1);
267 if (ret == NULL) {
268 return NULL;
269 }
270 for (i = 0, ii = 0; i < len; i++) {
271 if (s[i] != '_') {
272 ret[ii++] = s[i];
273 } else if (replacespace) {
274 ret[ii++] = ' ';
275 }
276 }
277 ret[ii] = '\0';
278 return ret;
279}
280
281
282/**
283 * create throbber toolbar item widget
284 *
285 * create a gtk entry widget with a completion attached
286 */
287static GtkToolItem *
288make_toolbar_item_throbber(bool sensitivity, bool edit)
289{
290 nserror res;
291 GtkToolItem *item;
292 GdkPixbuf *pixbuf;
293 GtkWidget *image;
294
295 res = nsgtk_throbber_get_frame(0, &pixbuf);
296 if (res != NSERROR_OK) {
297 return NULL;
298 }
299
300 if (edit) {
301 const char *msg;
302 msg = messages_get("ToolThrob");
303 item = gtk_tool_button_new(
304 GTK_WIDGET(gtk_image_new_from_pixbuf(pixbuf)),
305 msg);
306 } else {
307 item = gtk_tool_item_new();
308
309 image = gtk_image_new_from_pixbuf(pixbuf);
310 if (image != NULL) {
314 nsgtk_widget_set_margins(image, 3, 0);
315
316 gtk_container_add(GTK_CONTAINER(item), image);
317 }
318 }
319 gtk_widget_set_sensitive(GTK_WIDGET(item), sensitivity);
320
321 return item;
322}
323
324
325/**
326 * create url bar toolbar item widget
327 *
328 * create a gtk entry widget with a completion attached
329 *
330 * \param sensitivity if the entry should be created sensitive to input
331 * \param edit if the entry should be editable
332 */
333static GtkToolItem *
334make_toolbar_item_url_bar(bool sensitivity, bool edit)
335{
336 GtkToolItem *item;
337 GtkWidget *entry;
338 GtkEntryCompletion *completion;
339
340 entry = nsgtk_entry_new();
341
342 if (entry == NULL) {
343 return NULL;
344 }
347 "page-info-internal");
348
349 if (edit) {
350 gtk_entry_set_width_chars(GTK_ENTRY(entry), 9);
351
352 item = gtk_tool_button_new(NULL, "URL");
353 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), entry);
354 } else {
355 completion = gtk_entry_completion_new();
356 if (completion != NULL) {
357 gtk_entry_set_completion(GTK_ENTRY(entry), completion);
358 }
359
360 item = gtk_tool_item_new();
361 if (item == NULL) {
362 return NULL;
363 }
364
365 gtk_container_add(GTK_CONTAINER(item), entry);
366 gtk_tool_item_set_expand(item, TRUE);
367
368 }
369 gtk_widget_set_sensitive(GTK_WIDGET(item), TRUE);
370 gtk_widget_set_sensitive(GTK_WIDGET(entry), sensitivity);
371
372 return item;
373}
374
375
376/**
377 * create web search toolbar item widget
378 */
379static GtkToolItem *
380make_toolbar_item_websearch(bool sensitivity, bool edit)
381{
382 GtkToolItem *item;
383 nserror res;
384 GtkWidget *entry;
385 struct bitmap *bitmap;
386 GdkPixbuf *pixbuf = NULL;
387
389 if ((res == NSERROR_OK) && (bitmap != NULL)) {
391 }
392
393 entry = nsgtk_entry_new();
394
395 if (entry == NULL) {
396 return NULL;
397 }
398
399 if (pixbuf != NULL) {
402 pixbuf);
403 g_object_unref(pixbuf);
404 } else {
408 }
409
410 if (edit) {
411 gtk_entry_set_width_chars(GTK_ENTRY(entry), 9);
412
413 item = gtk_tool_button_new(NULL, "Web Search");
414 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item),
415 entry);
416 } else {
417 gtk_widget_set_size_request(entry, NSGTK_WEBSEARCH_WIDTH, -1);
418
419 item = gtk_tool_item_new();
420 if (item == NULL) {
421 return NULL;
422 }
423
424 gtk_container_add(GTK_CONTAINER(item), entry);
425 }
426 gtk_widget_set_sensitive(GTK_WIDGET(item), TRUE);
427 gtk_widget_set_sensitive(GTK_WIDGET(entry), sensitivity);
428
429 return item;
430}
431
432
433/**
434 * create local history toolbar item widget
435 */
436static GtkToolItem *
437make_toolbar_item_history(bool sensitivity, bool edit)
438{
439 GtkToolItem *item;
440 const char *msg = "H";
441 char *label = NULL;
442
443 if (edit) {
444 msg = messages_get("gtkLocalHistory");
445 }
446 label = remove_underscores(msg, false);
447 item = gtk_tool_button_new(NULL, label);
448 if (label != NULL) {
449 free(label);
450 }
451 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item), "local-history");
452
453 /* set history widget minimum width */
454 gtk_widget_set_size_request(GTK_WIDGET(item), 20, -1);
455 gtk_widget_set_sensitive(GTK_WIDGET(item), sensitivity);
456
457 return item;
458}
459
460
461/**
462 * create generic button toolbar item widget
463 */
464static GtkToolItem *
465make_toolbar_item_button(const char *labelmsg,
466 const char *iconname,
467 bool sensitivity,
468 bool edit)
469{
470 GtkToolItem *item;
471 char *label = NULL;
472
473 label = remove_underscores(messages_get(labelmsg), false);
474
475 item = gtk_tool_button_new(NULL, label);
476 if (label != NULL) {
477 free(label);
478 }
479
480 if (item != NULL) {
481 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item), iconname);
482
483 gtk_widget_set_sensitive(GTK_WIDGET(item), sensitivity);
484 if (edit) {
485 nsgtk_widget_set_margins(GTK_WIDGET(item), 0, 0);
486 }
487 }
488
489 return item;
490}
491
492
493/**
494 * widget factory for creation of toolbar item widgets
495 *
496 * \param i the id of the widget
497 * \param theme the theme to make the widgets from
498 * \return gtk widget
499 */
500static GtkToolItem *
502{
503 GtkToolItem *toolitem = NULL;
504
505 switch(itemid) {
506#define TOOLBAR_ITEM_y(identifier, label, iconame)
507#define TOOLBAR_ITEM_n(identifier, label, iconame)
508#define TOOLBAR_ITEM_t(identifier, label, iconame) \
509 case identifier: \
510 toolitem = make_toolbar_item_button(#label, iconame, sensitivity, false); \
511 break;
512#define TOOLBAR_ITEM_b(identifier, label, iconame) \
513 case identifier: \
514 toolitem = make_toolbar_item_button(#label, iconame, sensitivity, false); \
515 break;
516#define TOOLBAR_ITEM(identifier, name, snstvty, clicked, activate, label, iconame) \
517 TOOLBAR_ITEM_ ## clicked(identifier, label, iconame)
518
519#include "gtk/toolbar_items.h"
520
521#undef TOOLBAR_ITEM_t
522#undef TOOLBAR_ITEM_b
523#undef TOOLBAR_ITEM_n
524#undef TOOLBAR_ITEM_y
525#undef TOOLBAR_ITEM
526
527 case HISTORY_BUTTON:
528 toolitem = make_toolbar_item_history(sensitivity, false);
529 break;
530
531 case URL_BAR_ITEM:
532 toolitem = make_toolbar_item_url_bar(sensitivity, false);
533 break;
534
535 case THROBBER_ITEM:
536 toolitem = make_toolbar_item_throbber(sensitivity, false);
537 break;
538
539 case WEBSEARCH_ITEM:
540 toolitem = make_toolbar_item_websearch(sensitivity, false);
541 break;
542
543 default:
544 break;
545
546 }
547 return toolitem;
548}
549
550
551/**
552 * widget factory for creation of toolbar item widgets for the toolbox
553 *
554 * \param itemid the id of the widget
555 * \return gtk tool item widget
556 */
557static GtkToolItem *
559{
560 GtkToolItem *toolitem = NULL;
561
562 switch(itemid) {
563#define TOOLBAR_ITEM_y(identifier, label, iconame)
564#define TOOLBAR_ITEM_n(identifier, label, iconame)
565#define TOOLBAR_ITEM_t(identifier, label, iconame) \
566 case identifier: \
567 if (bar) { \
568 toolitem = make_toolbar_item_button(#label, iconame, true, true); \
569 } \
570 break;
571#define TOOLBAR_ITEM_b(identifier, label, iconame) \
572 case identifier: \
573 toolitem = make_toolbar_item_button(#label, iconame, true, true); \
574 break;
575#define TOOLBAR_ITEM(identifier, name, snstvty, clicked, activate, label, iconame) \
576 TOOLBAR_ITEM_ ## clicked(identifier, label, iconame)
577
578#include "gtk/toolbar_items.h"
579
580#undef TOOLBAR_ITEM_t
581#undef TOOLBAR_ITEM_b
582#undef TOOLBAR_ITEM_n
583#undef TOOLBAR_ITEM_y
584#undef TOOLBAR_ITEM
585
586 case HISTORY_BUTTON:
587 toolitem = make_toolbar_item_history(true, true);
588 break;
589
590 case URL_BAR_ITEM:
591 toolitem = make_toolbar_item_url_bar(false, true);
592 break;
593
594 case THROBBER_ITEM:
595 toolitem = make_toolbar_item_throbber(true, true);
596 break;
597
598 case WEBSEARCH_ITEM:
599 toolitem = make_toolbar_item_websearch(false, true);
600 break;
601
602 default:
603 break;
604
605 }
606 return toolitem;
607}
608
609
610/**
611 * target entry for drag source
612 */
613static GtkTargetEntry target_entry = {
614 (char *)"nsgtk_button_data",
615 GTK_TARGET_SAME_APP,
616 0
617};
618
619
620/**
621 * find the toolbar item with a given location.
622 *
623 * \param tb the toolbar instance
624 * \param locaction the location to search for
625 * \return the item id for a location
626 */
628itemid_from_location(struct nsgtk_toolbar *tb, int location)
629{
630 int iidx;
631 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
632 if (tb->items[iidx].location == location) {
633 break;
634 }
635 }
636 return iidx;
637}
638
639
640/**
641 * save toolbar settings to file
642 */
643static nserror
645{
646 int iidx; /* item index */
647 char *order; /* item ordering */
648 char *start; /* start of next item name to be output */
649 int orderlen = 0; /* length of item ordering */
651 int location;
652 char *choices = NULL;
653
654 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
655 if (tb->items[iidx].location != INACTIVE_LOCATION) {
656 orderlen += strlen(tb->items[iidx].name);
657 orderlen++; /* allow for separator */
658 }
659 }
660
661 /* ensure there are some items to store */
662 if (orderlen == 0) {
663 return NSERROR_INVALID;
664 }
665
666 order = malloc(orderlen);
667 if (order == NULL) {
668 return NSERROR_NOMEM;
669 }
670
671 start = order;
672
673 for (location = BACK_BUTTON;
674 location < PLACEHOLDER_BUTTON;
675 location++) {
676 int written;
677 itemid = itemid_from_location(tb, location);
678 if (itemid == PLACEHOLDER_BUTTON) {
679 /* no more filled locations */
680 break;
681 }
682 written = snprintf(start,
683 orderlen - (start - order),
684 "%s/",
685 tb->items[itemid].name);
686 if ((written < 0) ||
687 (written >= orderlen - (start - order))) {
688 free(order);
689 return NSERROR_UNKNOWN;
690 }
691 start += written;
692
693 if ((start - order) >= orderlen) {
694 break;
695 }
696 }
697
698 order[orderlen - 1] = 0;
699
700 nsoption_set_charp(toolbar_items, order);
701
702 /* ensure choices are saved */
703 netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
704 if (choices != NULL) {
705 nsoption_write(choices, NULL, NULL);
706 free(choices);
707 }
708
709 return NSERROR_OK;
710}
711
712
713/**
714 * connect signals to a toolbar item in a customisation toolbar
715 *
716 * \param tb The toolbar
717 * \param itemid The item id within to toolbar to connect
718 * \param NSERROR_OK on success
719 */
720static nserror
722{
723 /* set toolbar items to be a drag source */
724 gtk_tool_item_set_use_drag_window(tb->items[itemid].button, TRUE);
725 gtk_drag_source_set(GTK_WIDGET(tb->items[itemid].button),
726 GDK_BUTTON1_MASK,
728 1,
729 GDK_ACTION_COPY);
730 g_signal_connect(tb->items[itemid].button,
731 "drag-data-get",
732 G_CALLBACK(tb->items[itemid].dataminus),
733 tb);
734 return NSERROR_OK;
735}
736
737
738/**
739 * customisation container handler for drag drop signal
740 *
741 * called when a widget is dropped onto the store window
742 */
743static gboolean
745 GdkDragContext *gdc,
746 gint x, gint y,
747 guint time,
748 gpointer data)
749{
750 struct nsgtk_toolbar_customisation *tbc;
751 tbc = (struct nsgtk_toolbar_customisation *)data;
752 int location;
753 int itemid;
754
755 if ((tbc->dragfrom) || (tbc->dragitem == -1)) {
756 tbc->dragitem = -1;
757 return FALSE;
758 }
759
760 if (tbc->toolbar.items[tbc->dragitem].location == INACTIVE_LOCATION) {
761 tbc->dragitem = -1;
762 gtk_drag_finish(gdc, TRUE, TRUE, time);
763 return FALSE;
764
765 }
766
767 /* update the locations for all the subsequent toolbar items */
768 for (location = tbc->toolbar.items[tbc->dragitem].location;
769 location < PLACEHOLDER_BUTTON;
770 location++) {
771 itemid = itemid_from_location(&tbc->toolbar, location);
772 if (itemid == PLACEHOLDER_BUTTON) {
773 break;
774 }
775 tbc->toolbar.items[itemid].location--;
776 }
777
778 /* remove existing item */
779 tbc->toolbar.items[tbc->dragitem].location = -1;
780 gtk_container_remove(GTK_CONTAINER(tbc->toolbar.widget),
781 GTK_WIDGET(tbc->toolbar.items[tbc->dragitem].button));
782
783 tbc->dragitem = -1;
784 gtk_drag_finish(gdc, TRUE, TRUE, time);
785 return FALSE;
786}
787
788
789/**
790 * customisation container handler for drag motion signal
791 *
792 * called when hovering above the store
793 */
794static gboolean
796 GdkDragContext *gdc,
797 gint x, gint y,
798 guint time,
799 gpointer data)
800{
801 return FALSE;
802}
803
804
805/**
806 * customisation toolbar handler for drag drop signal
807 *
808 * called when a widget is dropped onto the toolbar
809 */
810static gboolean
812 GdkDragContext *gdc,
813 gint x,
814 gint y,
815 guint time,
816 gpointer data)
817{
818 struct nsgtk_toolbar_customisation *tbc;
819 tbc = (struct nsgtk_toolbar_customisation *)data;
820 gint position; /* drop position in toolbar */
821 int location;
822 int itemid;
823 struct nsgtk_toolbar_item *dragitem; /* toolbar item being dragged */
824
825 position = gtk_toolbar_get_drop_index(tbc->toolbar.widget, x, y);
826 if (tbc->dragitem == -1) {
827 return TRUE;
828 }
829
830 /* pure conveiance variable */
831 dragitem = &tbc->toolbar.items[tbc->dragitem];
832
833 /* deal with replacing existing item in toolbar */
834 if (dragitem->location != INACTIVE_LOCATION) {
835 if (dragitem->location < position) {
836 position--;
837 }
838
839 /* update the locations for all the subsequent toolbar items */
840 for (location = dragitem->location;
842 location++) {
843 itemid = itemid_from_location(&tbc->toolbar, location);
844 if (itemid == PLACEHOLDER_BUTTON) {
845 break;
846 }
847 tbc->toolbar.items[itemid].location--;
848 }
849
850 /* remove existing item */
851 dragitem->location = INACTIVE_LOCATION;
852 gtk_container_remove(GTK_CONTAINER(tbc->toolbar.widget),
853 GTK_WIDGET(dragitem->button));
854 }
855
856
857 dragitem->button = make_toolbox_item(tbc->dragitem, true);
858
859 if (dragitem->button == NULL) {
860 nsgtk_warning("NoMemory", 0);
861 return TRUE;
862 }
863
864 /* update locations */
865 for (location = PLACEHOLDER_BUTTON; location >= position; location--) {
866 itemid = itemid_from_location(&tbc->toolbar, location);
867 if (itemid != PLACEHOLDER_BUTTON) {
868 tbc->toolbar.items[itemid].location++;
869 }
870 }
871 dragitem->location = position;
872
873 gtk_toolbar_insert(tbc->toolbar.widget,
874 dragitem->button,
875 dragitem->location);
876
878 gtk_widget_show_all(GTK_WIDGET(dragitem->button));
879 tbc->dragitem = -1;
880 return TRUE;
881}
882
883
884/**
885 * customisation toolbar handler for drag data received signal
886 *
887 * connected to toolbutton drop; perhaps one day it'll work properly
888 * so it may replace the global current_button
889 */
890static gboolean
892 GdkDragContext *gdc,
893 gint x,
894 gint y,
895 GtkSelectionData *selection,
896 guint info,
897 guint time,
898 gpointer data)
899{
900 return FALSE;
901}
902
903
904/**
905 * customisation toolbar handler for drag motion signal
906 *
907 * called when hovering an item above the toolbar
908 */
909static gboolean
911 GdkDragContext *gdc,
912 gint x,
913 gint y,
914 guint time,
915 gpointer data)
916{
917 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
918 GtkToolItem *item;
919 gint position; /* position in toolbar */
920
921 item = gtk_tool_button_new(NULL, NULL);
922 position = gtk_toolbar_get_drop_index(tb->widget, x, y);
923
924 gtk_toolbar_set_drop_highlight_item(tb->widget, item, position);
925
926 return FALSE; /* drag not in drop zone */
927}
928
929
930/**
931 * customisation toolbar handler for drag leave signal
932 *
933 * called when hovering stops
934 */
935static void
937 GdkDragContext *gdc,
938 guint time,
939 gpointer data)
940{
941 gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(widget), NULL, 0);
942}
943
944
945/**
946 * create a new browser window
947 *
948 * creates a browser window with default url depending on user choices.
949 *
950 * \param bw The browser window to pass for existing window/
951 * \param intab true if the new window should be in a tab else false
952 * for new window.
953 * \return NSERROR_OK on success else error code.
954 */
955static nserror
957{
958 nserror res = NSERROR_OK;
959 nsurl *url = NULL;
961
962 if (intab) {
963 flags |= BW_CREATE_TAB;
964 }
965
966 if (!nsoption_bool(new_blank)) {
967 const char *addr;
968 if (nsoption_charp(homepage_url) != NULL) {
969 addr = nsoption_charp(homepage_url);
970 } else {
971 addr = NETSURF_HOMEPAGE;
972 }
973 res = nsurl_create(addr, &url);
974 }
975
976 if (res == NSERROR_OK) {
977 res = browser_window_create(flags, url, NULL, bw, NULL);
978 }
979
980 if (url != NULL) {
981 nsurl_unref(url);
982 }
983
984 return res;
985}
986
987
988/**
989 * Apply the user toolbar button settings from configuration
990 *
991 * GTK specific user option string is a set of fields arranged as
992 * [itemreference];[itemlocation]|[itemreference];[itemlocation]| etc
993 *
994 * \param tb The toolbar to apply customisation to
995 * \param NSERROR_OK on success else error code.
996 */
997static nserror
999{
1000 const char *tbitems; /* item order user config */
1001 const char *start;
1002 const char *end;
1003 int iidx; /* item index */
1004 int location = 0; /* location index */
1005
1006 /* set all button locations to inactive */
1007 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
1008 tb->items[iidx].location = INACTIVE_LOCATION;
1009 }
1010
1011 tbitems = nsoption_charp(toolbar_items);
1012 if (tbitems == NULL) {
1013 tbitems = "";
1014 }
1015
1016 end = tbitems;
1017 while (*end != 0) {
1018 start = end;
1019 while ((*end != 0) && (*end !='/')) {
1020 end++;
1021 }
1022
1023 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
1024 if (((ssize_t)strlen(tb->items[iidx].name) == (end - start)) &&
1025 (strncmp(tb->items[iidx].name, start, end - start) == 0)) {
1026 tb->items[iidx].location = location++;
1027 break;
1028 }
1029 }
1030
1031 if (*end == '/') {
1032 end++;
1033 }
1034 }
1035
1036 if (location == 0) {
1037 /* completely failed to create any buttons so use defaults */
1038 tb->items[BACK_BUTTON].location = location++;
1039 tb->items[HISTORY_BUTTON].location = location++;
1040 tb->items[FORWARD_BUTTON].location = location++;
1041 tb->items[RELOADSTOP_BUTTON].location = location++;
1042 tb->items[URL_BAR_ITEM].location = location++;
1043 tb->items[WEBSEARCH_ITEM].location = location++;
1044 tb->items[OPENMENU_BUTTON].location = location++;
1045 tb->items[THROBBER_ITEM].location = location++;
1046 }
1047
1048
1049 return NSERROR_OK;
1050}
1051
1052
1053/**
1054 * callback function to remove a widget from a container
1055 */
1056static void container_remove_widget(GtkWidget *widget, gpointer data)
1057{
1058 GtkContainer *container = GTK_CONTAINER(data);
1059 gtk_container_remove(container, widget);
1060}
1061
1062
1063/**
1064 * populates a toolbar with widgets in correct order
1065 *
1066 * \param tb toolbar
1067 * \return NSERROR_OK on success else error code.
1068 */
1070{
1071 int location; /* location index */
1072 int itemid;
1073
1074 /* clear the toolbar container of all widgets */
1075 gtk_container_foreach(GTK_CONTAINER(tb->widget),
1077 tb->widget);
1078
1079 /* add widgets to toolbar */
1080 for (location = 0; location < PLACEHOLDER_BUTTON; location++) {
1081 itemid = itemid_from_location(tb, location);
1082 if (itemid == PLACEHOLDER_BUTTON) {
1083 break;
1084 }
1085 tb->items[itemid].button =
1086 make_toolbar_item(itemid,
1087 tb->items[itemid].sensitivity);
1088
1089 gtk_toolbar_insert(tb->widget,
1090 tb->items[itemid].button,
1091 location);
1092 }
1093
1094 gtk_widget_show_all(GTK_WIDGET(tb->widget));
1095
1096 return NSERROR_OK;
1097}
1098
1099
1100/**
1101 * populates the customization toolbar with widgets in correct order
1102 *
1103 * \param tb toolbar
1104 * \return NSERROR_OK on success else error code.
1105 */
1107{
1108 int location; /* location index */
1109 int itemid;
1110
1111 /* clear the toolbar container of all widgets */
1112 gtk_container_foreach(GTK_CONTAINER(tb->widget),
1114 tb->widget);
1115
1116 /* add widgets to toolbar */
1117 for (location = 0; location < PLACEHOLDER_BUTTON; location++) {
1118 itemid = itemid_from_location(tb, location);
1119 if (itemid == PLACEHOLDER_BUTTON) {
1120 break;
1121 }
1122 tb->items[itemid].button = make_toolbox_item(itemid, true);
1123
1124 gtk_toolbar_insert(tb->widget,
1125 tb->items[itemid].button,
1126 location);
1127 }
1128
1129 gtk_widget_show_all(GTK_WIDGET(tb->widget));
1130
1131 return NSERROR_OK;
1132}
1133
1134
1135/**
1136 * find the toolbar item with a given gtk widget.
1137 *
1138 * \param tb the toolbar instance
1139 * \param toolitem the tool item widget to search for
1140 * \return the item id matching the widget
1141 */
1143itemid_from_gtktoolitem(struct nsgtk_toolbar *tb, GtkToolItem *toolitem)
1144{
1145 int iidx;
1146 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
1147 if ((tb->items[iidx].location != INACTIVE_LOCATION) &&
1148 (tb->items[iidx].button == toolitem)) {
1149 break;
1150 }
1151 }
1152 return iidx;
1153}
1154
1155
1156/**
1157 * set a toolbar items sensitivity
1158 *
1159 * note this does not set menu items sensitivity
1160 */
1161static nserror
1162set_item_sensitivity(struct nsgtk_toolbar_item *item, bool sensitivity)
1163{
1164 if (item->sensitivity != sensitivity) {
1165 /* item requires sensitivity changing */
1166 item->sensitivity = sensitivity;
1167
1168 if ((item->location != -1) && (item->button != NULL)) {
1169 gtk_widget_set_sensitive(GTK_WIDGET(item->button),
1170 item->sensitivity);
1171 }
1172 }
1173
1174 return NSERROR_OK;
1175}
1176
1177
1178/**
1179 * set an item to its alternative action
1180 *
1181 * this is currently only used for the stop/reload button where we
1182 * also reuse the item sensitivity for the state indicator.
1183 *
1184 * \param tb the toolbar instance
1185 */
1186static nserror set_item_action(struct nsgtk_toolbar *tb, int itemid, bool alt)
1187{
1188 const char *iconname;
1189 char *label = NULL;
1190
1191 if (itemid != RELOADSTOP_BUTTON) {
1192 return NSERROR_INVALID;
1193 }
1194 if (tb->items[itemid].location == -1) {
1195 return NSERROR_OK;
1196 }
1197 tb->items[itemid].sensitivity = alt;
1198
1199 if (tb->items[itemid].button == NULL) {
1200 return NSERROR_INVALID;
1201 }
1202
1203 if (tb->items[itemid].sensitivity) {
1204 iconname = NSGTK_STOCK_REFRESH;
1205 label = remove_underscores(messages_get("Reload"), false);
1206
1207 } else {
1208 iconname = NSGTK_STOCK_STOP;
1209 label = remove_underscores(messages_get("gtkStop"), false);
1210
1211 }
1212 gtk_tool_button_set_label(GTK_TOOL_BUTTON(tb->items[itemid].button),
1213 label);
1214
1215 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(tb->items[itemid].button),
1216 iconname);
1217
1218 gtk_widget_set_sensitive(GTK_WIDGET(tb->items[itemid].button), TRUE);
1219
1220 if (label != NULL) {
1221 free(label);
1222 }
1223
1224 return NSERROR_OK;
1225}
1226
1227
1228/**
1229 * cause the toolbar browsing context to navigate to a new url.
1230 *
1231 * \param tb the toolbar context.
1232 * \param urltxt The url string.
1233 * \return NSERROR_OK on success else appropriate error code.
1234 */
1235static nserror
1236toolbar_navigate_to_url(struct nsgtk_toolbar *tb, const char *urltxt)
1237{
1238 struct browser_window *bw;
1239 nsurl *url;
1240 nserror res;
1241
1242 res = nsurl_create(urltxt, &url);
1243 if (res != NSERROR_OK) {
1244 return res;
1245 }
1246
1247 bw = tb->get_bw(tb->get_ctx);
1248
1250 url,
1251 NULL,
1253 NULL,
1254 NULL,
1255 NULL);
1256 nsurl_unref(url);
1257
1258 return res;
1259}
1260
1261
1262/**
1263 * run a gtk file chooser as a save dialog to obtain a path
1264 */
1265static nserror
1267 const char *title,
1268 GtkWindow *parent,
1269 bool folder,
1270 gchar **path_out)
1271{
1272 nserror res;
1273 GtkWidget *fc; /* file chooser widget */
1274 GtkFileChooserAction action;
1275 char *path; /* proposed path */
1276
1278 /* cannot save a page with no content */
1279 return NSERROR_INVALID;
1280 }
1281
1282 if (folder) {
1283 action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
1284 } else {
1285 action = GTK_FILE_CHOOSER_ACTION_SAVE;
1286 }
1287
1288 fc = gtk_file_chooser_dialog_new(title,
1289 parent,
1290 action,
1292 GTK_RESPONSE_CANCEL,
1294 GTK_RESPONSE_ACCEPT,
1295 NULL);
1296
1297 /* set a default file name */
1299 if (res != NSERROR_OK) {
1300 path = strdup(messages_get("SaveText"));
1301 if (path == NULL) {
1302 gtk_widget_destroy(fc);
1303 return NSERROR_NOMEM;
1304 }
1305 }
1306
1307 if ((!folder) || (access(path, F_OK) != 0)) {
1308 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), path);
1309 }
1310 free(path);
1311
1312 /* confirm overwriting */
1313 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc), TRUE);
1314
1315 /* run the dialog to let user select path */
1316 if (gtk_dialog_run(GTK_DIALOG(fc)) != GTK_RESPONSE_ACCEPT) {
1317 gtk_widget_destroy(fc);
1318 return NSERROR_NOT_FOUND;
1319 }
1320
1321 *path_out = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
1322
1323 gtk_widget_destroy(fc);
1324
1325 return NSERROR_OK;
1326}
1327
1328
1329/**
1330 * connect all signals to widgets in a customisation
1331 */
1332static nserror
1334{
1335 int iidx;
1336
1337 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
1338 /* skip inactive items in toolbar */
1339 if (tb->items[iidx].location != INACTIVE_LOCATION) {
1341 }
1342 }
1343
1344 /* add move button listeners */
1345 g_signal_connect(tb->widget,
1346 "drag-drop",
1348 tb);
1349 g_signal_connect(tb->widget,
1350 "drag-data-received",
1352 tb);
1353 g_signal_connect(tb->widget,
1354 "drag-motion",
1356 tb);
1357 g_signal_connect(tb->widget,
1358 "drag-leave",
1360 tb);
1361
1362 /* set data types */
1363 gtk_drag_dest_set(GTK_WIDGET(tb->widget),
1364 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
1365 &target_entry,
1366 1,
1367 GDK_ACTION_COPY);
1368
1369 return NSERROR_OK;
1370}
1371
1372
1373static void
1374item_size_allocate_cb(GtkWidget *widget,
1375 GdkRectangle *alloc,
1376 gpointer user_data)
1377{
1378 if (alloc->width > NSGTK_BUTTON_WIDTH) {
1379 alloc->width = NSGTK_BUTTON_WIDTH;
1380 }
1381 if (alloc->height > NSGTK_BUTTON_HEIGHT) {
1382 alloc->height = NSGTK_BUTTON_HEIGHT;
1383 }
1384 gtk_widget_set_allocation(widget, alloc);
1385}
1386
1387
1388/**
1389 * add a row to a toolbar customisation toolbox
1390 *
1391 * \param tbc The toolbar customisation context
1392 * \param startitem The item index of the beginning of the row
1393 * \param enditem The item index of the beginning of the next row
1394 * \return NSERROR_OK on successs else error
1395 */
1396static nserror
1398 int startitem,
1399 int enditem)
1400{
1401 GtkToolbar *rowbar;
1402 int iidx;
1403
1404 rowbar = GTK_TOOLBAR(gtk_toolbar_new());
1405 if (rowbar == NULL) {
1406 return NSERROR_NOMEM;
1407 }
1408
1409 gtk_toolbar_set_style(rowbar, GTK_TOOLBAR_BOTH);
1410 gtk_toolbar_set_icon_size(rowbar, GTK_ICON_SIZE_LARGE_TOOLBAR);
1411 gtk_box_pack_start(tbc->toolbox, GTK_WIDGET(rowbar), FALSE, FALSE, 0);
1412
1413 for (iidx = startitem; iidx < enditem; iidx++) {
1414 if (tbc->items[iidx] == NULL) {
1415 /* skip any widgets that failed to initialise */
1416 continue;
1417 }
1418 gtk_widget_set_size_request(GTK_WIDGET(tbc->items[iidx]),
1421 gtk_tool_item_set_use_drag_window(tbc->items[iidx], TRUE);
1422 gtk_drag_source_set(GTK_WIDGET(tbc->items[iidx]),
1423 GDK_BUTTON1_MASK,
1424 &target_entry,
1425 1,
1426 GDK_ACTION_COPY);
1427 g_signal_connect(tbc->items[iidx],
1428 "drag-data-get",
1429 G_CALLBACK(tbc->toolbar.items[iidx].dataplus),
1430 &tbc->toolbar);
1431 g_signal_connect(tbc->items[iidx],
1432 "size-allocate",
1433 G_CALLBACK(item_size_allocate_cb),
1434 NULL);
1435 gtk_toolbar_insert(rowbar, tbc->items[iidx], -1);
1436 }
1437 return NSERROR_OK;
1438}
1439
1440
1441/**
1442 * creates widgets in customisation toolbox
1443 *
1444 * \param tbc The toolbar customisation context
1445 * \param width The width to layout the toolbox to
1446 * \return NSERROR_OK on success else error code.
1447 */
1448static nserror
1450 int width)
1451{
1452 int columns; /* number of items in a single row */
1453 int curcol; /* current column in creation */
1454 int iidx; /* item index */
1455 int startidx; /* index of item at start of row */
1456
1457 /* ensure there are a minimum number of items per row */
1461 }
1462
1463 curcol = 0;
1464 for (iidx = startidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
1465 if (curcol >= columns) {
1466 add_toolbox_row(tbc, startidx, iidx);
1467 curcol = 0;
1468 startidx = iidx;
1469 }
1470 tbc->items[iidx] = make_toolbox_item(iidx, false);
1471 if (tbc->items[iidx] != NULL) {
1472 curcol++;
1473 }
1474 }
1475 if (curcol > 0) {
1476 add_toolbox_row(tbc, startidx, iidx);
1477 }
1478
1479 return NSERROR_OK;
1480}
1481
1482
1483/**
1484 * update toolbar in customisation to user settings
1485 */
1486static nserror
1488{
1489 nserror res;
1490
1492 if (res != NSERROR_OK) {
1493 return res;
1494 }
1495
1496 /* populate toolbar widget */
1498 if (res != NSERROR_OK) {
1499 return res;
1500 }
1501
1502 /* ensure icon sizes and text labels on toolbar are set */
1503 res = nsgtk_toolbar_restyle(&tbc->toolbar);
1504 if (res != NSERROR_OK) {
1505 return res;
1506 }
1507
1508 /* attach handlers to toolbar widgets */
1510 if (res != NSERROR_OK) {
1511 return res;
1512 }
1513
1514 return NSERROR_OK;
1515}
1516
1517
1518/**
1519 * customisation apply handler for clicked signal
1520 *
1521 * when 'save settings' button is clicked
1522 */
1523static gboolean
1524customisation_apply_clicked_cb(GtkWidget *widget, gpointer data)
1525{
1526 struct nsgtk_toolbar_customisation *tbc;
1527 tbc = (struct nsgtk_toolbar_customisation *)data;
1528
1529 /* save state to file, update toolbars for all windows */
1532 gtk_widget_destroy(tbc->container);
1533
1534 return TRUE;
1535}
1536
1537
1538/**
1539 * customisation reset handler for clicked signal
1540 *
1541 * when 'reload defaults' button is clicked
1542 */
1543static gboolean
1544customisation_reset_clicked_cb(GtkWidget *widget, gpointer data)
1545{
1546 struct nsgtk_toolbar_customisation *tbc;
1547 tbc = (struct nsgtk_toolbar_customisation *)data;
1548
1550
1551 return TRUE;
1552}
1553
1554
1555/**
1556 * customisation container destroy handler
1557 */
1558static void customisation_container_destroy_cb(GtkWidget *widget, gpointer data)
1559{
1560 struct nsgtk_toolbar_customisation *tbc;
1561 tbc = (struct nsgtk_toolbar_customisation *)data;
1562
1563 free(tbc);
1564}
1565
1566/*
1567 * Toolbar button clicked handlers
1568 */
1569
1570/**
1571 * create a toolbar customisation tab
1572 *
1573 * this is completely different approach to previous implementation. it
1574 * is not modal and the toolbar configuration is performed completely
1575 * within the tab. once the user is happy they can apply the change or
1576 * cancel as they see fit while continuing to use the browser as usual.
1577 */
1578static gboolean cutomize_button_clicked_cb(GtkWidget *widget, gpointer data)
1579{
1580 struct nsgtk_toolbar_customisation *tbc;
1581 nserror res;
1582 GtkBuilder *builder;
1583 GtkNotebook *notebook; /* notebook containing widget */
1584 GtkAllocation notebook_alloc; /* notebook size allocation */
1585 int iidx; /* item index */
1586
1587 /* obtain the notebook being added to */
1588 notebook = GTK_NOTEBOOK(gtk_widget_get_ancestor(widget,
1589 GTK_TYPE_NOTEBOOK));
1590 if (notebook == NULL) {
1591 return TRUE;
1592 }
1593
1594 /* create builder */
1595 res = nsgtk_builder_new_from_resname("toolbar", &builder);
1596 if (res != NSERROR_OK) {
1597 NSLOG(netsurf, INFO, "Toolbar UI builder init failed");
1598 return TRUE;
1599 }
1600 gtk_builder_connect_signals(builder, NULL);
1601
1602 /* create nsgtk_toolbar_customisation which has nsgtk_toolbar
1603 * at the front so we can reuse functions that take
1604 * nsgtk_toolbar
1605 */
1606 tbc = calloc(1, sizeof(struct nsgtk_toolbar_customisation));
1607 if (tbc == NULL) {
1608 g_object_unref(builder);
1609 return TRUE;
1610 }
1611
1612 /* get container box widget which forms a page of the tabs */
1613 tbc->container = GTK_WIDGET(gtk_builder_get_object(builder, "customisation"));
1614 if (tbc->container == NULL) {
1615 goto cutomize_button_clicked_cb_error;
1616 }
1617
1618 /* vertical box for the toolbox to drag items into and out of */
1619 tbc->toolbox = GTK_BOX(gtk_builder_get_object(builder, "toolbox"));
1620 if (tbc->toolbox == NULL) {
1621 goto cutomize_button_clicked_cb_error;
1622 }
1623
1624 /* customisation toolbar container */
1625 tbc->toolbar.widget = GTK_TOOLBAR(gtk_builder_get_object(builder, "toolbar"));
1626 if (tbc->toolbar.widget == NULL) {
1627 goto cutomize_button_clicked_cb_error;
1628 }
1629
1630 /* build customisation toolbar */
1631 gtk_toolbar_set_show_arrow(tbc->toolbar.widget, TRUE);
1632
1633 for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) {
1634 res = toolbar_item_create(iidx, &tbc->toolbar.items[iidx]);
1635 if (res != NSERROR_OK) {
1636 goto cutomize_button_clicked_cb_error;
1637 }
1638 }
1639
1641 if (res != NSERROR_OK) {
1642 goto cutomize_button_clicked_cb_error;
1643 }
1644
1645 /* use toolbox for widgets to drag to/from */
1646 gtk_widget_get_allocation(GTK_WIDGET(notebook), &notebook_alloc);
1647
1648 res = toolbar_customisation_create_toolbox(tbc, notebook_alloc.width);
1649 if (res != NSERROR_OK) {
1650 goto cutomize_button_clicked_cb_error;
1651 }
1652
1653 /* configure the container */
1654 gtk_drag_dest_set(GTK_WIDGET(tbc->container),
1655 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
1656 &target_entry,
1657 1,
1658 GDK_ACTION_COPY);
1659
1660 /* discard button calls destroy */
1661 g_signal_connect_swapped(GTK_WIDGET(gtk_builder_get_object(builder,
1662 "discard")),
1663 "clicked",
1664 G_CALLBACK(gtk_widget_destroy),
1665 tbc->container);
1666
1667 /* save and update on apply button */
1668 g_signal_connect(GTK_WIDGET(gtk_builder_get_object(builder, "apply")),
1669 "clicked",
1671 tbc);
1672
1673 g_signal_connect(GTK_WIDGET(gtk_builder_get_object(builder, "reset")),
1674 "clicked",
1676 tbc);
1677
1678 /* close and cleanup on delete signal */
1679 g_signal_connect(tbc->container,
1680 "destroy",
1682 tbc);
1683
1684
1685 g_signal_connect(tbc->container,
1686 "drag-drop",
1688 tbc);
1689
1690 g_signal_connect(tbc->container,
1691 "drag-motion",
1693 tbc);
1694
1695
1696 nsgtk_tab_add_page(notebook,
1697 tbc->container,
1698 false,
1699 messages_get("gtkCustomizeToolbarTitle"),
1701
1702
1703 /* safe to drop the reference to the builder as the container is
1704 * referenced by the notebook now.
1705 */
1706 g_object_unref(builder);
1707
1708 return TRUE;
1709
1710 cutomize_button_clicked_cb_error:
1711 free(tbc);
1712 g_object_unref(builder);
1713 return TRUE;
1714
1715}
1716
1717
1718/**
1719 * callback for all toolbar items widget size allocation
1720 *
1721 * handler connected to all toolbar items for the size-allocate signal
1722 *
1723 * \param widget The widget the signal is being delivered to.
1724 * \param alloc The size allocation being set.
1725 * \param data The toolbar context passed when the signal was connected
1726 */
1727static void
1729 GtkAllocation *alloc,
1730 gpointer data)
1731{
1732 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1733 nsgtk_toolbar_button itemid;
1734
1735 itemid = itemid_from_gtktoolitem(tb, GTK_TOOL_ITEM(widget));
1736
1737 if ((tb->toolbarmem == alloc->x) ||
1738 (tb->items[itemid].location < tb->items[HISTORY_BUTTON].location)) {
1739 /*
1740 * no reallocation after first adjustment,
1741 * no reallocation for buttons left of history button
1742 */
1743 return;
1744 }
1745
1746 if (itemid == HISTORY_BUTTON) {
1747 if (alloc->width == 20) {
1748 return;
1749 }
1750
1751 tb->toolbarbase = alloc->y + alloc->height;
1752 tb->historybase = alloc->x + 20;
1753 if (tb->offset == 0) {
1754 tb->offset = alloc->width - 20;
1755 }
1756 alloc->width = 20;
1757 } else if (tb->items[itemid].location <= tb->items[URL_BAR_ITEM].location) {
1758 alloc->x -= tb->offset;
1759 if (itemid == URL_BAR_ITEM) {
1760 alloc->width += tb->offset;
1761 }
1762 }
1763 tb->toolbarmem = alloc->x;
1764
1765 gtk_widget_size_allocate(widget, alloc);
1766}
1767
1768
1769/**
1770 * handler for back tool bar item clicked signal
1771 *
1772 * \param widget The widget the signal is being delivered to.
1773 * \param data The toolbar context passed when the signal was connected
1774 * \return TRUE
1775 */
1776static gboolean
1777back_button_clicked_cb(GtkWidget *widget, gpointer data)
1778{
1779 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1780 struct browser_window *bw;
1781
1782 bw = tb->get_bw(tb->get_ctx);
1783
1784 if ((bw != NULL) && browser_window_history_back_available(bw)) {
1785 /* clear potential search effects */
1787
1789
1794
1796 }
1797 return TRUE;
1798}
1799
1800
1801/**
1802 * handler for forward tool bar item clicked signal
1803 *
1804 * \param widget The widget the signal is being delivered to.
1805 * \param data The toolbar context passed when the signal was connected
1806 * \return TRUE
1807 */
1808static gboolean
1809forward_button_clicked_cb(GtkWidget *widget, gpointer data)
1810{
1811 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1812 struct browser_window *bw;
1813
1814 bw = tb->get_bw(tb->get_ctx);
1815
1817 /* clear potential search effects */
1819
1821
1827 }
1828 return TRUE;
1829}
1830
1831
1832/**
1833 * handler for stop tool bar item clicked signal
1834 *
1835 * \param widget The widget the signal is being delivered to.
1836 * \param data The toolbar context passed when the signal was connected
1837 * \return TRUE
1838 */
1839static gboolean
1840stop_button_clicked_cb(GtkWidget *widget, gpointer data)
1841{
1842 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1843
1845
1846 return TRUE;
1847}
1848
1849
1850/**
1851 * handler for reload tool bar item clicked signal
1852 *
1853 * \param widget The widget the signal is being delivered to.
1854 * \param data The toolbar context passed when the signal was connected
1855 * \return TRUE
1856 */
1857static gboolean
1858reload_button_clicked_cb(GtkWidget *widget, gpointer data)
1859{
1860 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1861 struct browser_window *bw;
1862
1863 bw = tb->get_bw(tb->get_ctx);
1864
1865 /* clear potential search effects */
1867
1869
1870 return TRUE;
1871}
1872
1873
1874/**
1875 * handler for reload/stop tool bar item clicked signal
1876 *
1877 * \param widget The widget the signal is being delivered to.
1878 * \param data The toolbar context passed when the signal was connected
1879 * \return TRUE
1880 */
1881static gboolean
1882reloadstop_button_clicked_cb(GtkWidget *widget, gpointer data)
1883{
1884 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1885 struct browser_window *bw;
1886
1887 bw = tb->get_bw(tb->get_ctx);
1888
1889 /* clear potential search effects */
1891
1894 } else {
1896 }
1897
1898 return TRUE;
1899}
1900
1901
1902/**
1903 * handler for home tool bar item clicked signal
1904 *
1905 * \param widget The widget the signal is being delivered to.
1906 * \param data The toolbar context passed when the signal was connected
1907 * \return TRUE
1908 */
1909static gboolean
1910home_button_clicked_cb(GtkWidget *widget, gpointer data)
1911{
1912 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1913 nserror res;
1914 const char *addr;
1915
1916 if (nsoption_charp(homepage_url) != NULL) {
1917 addr = nsoption_charp(homepage_url);
1918 } else {
1919 addr = NETSURF_HOMEPAGE;
1920 }
1921
1922 res = toolbar_navigate_to_url(tb, addr);
1923 if (res != NSERROR_OK) {
1925 }
1926
1927 return TRUE;
1928}
1929
1930
1931/**
1932 * callback for url entry widget activation
1933 *
1934 * handler connected to url entry widget for the activate signal
1935 *
1936 * \param widget The widget the signal is being delivered to.
1937 * \param data The toolbar context passed when the signal was connected
1938 * \return TRUE to allow activation.
1939 */
1940static gboolean url_entry_activate_cb(GtkWidget *widget, gpointer data)
1941{
1942 nserror res;
1943 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1944 struct browser_window *bw;
1945 nsurl *url;
1946
1947 res = search_web_omni(gtk_entry_get_text(GTK_ENTRY(widget)),
1949 &url);
1950 if (res == NSERROR_OK) {
1951 bw = tb->get_bw(tb->get_ctx);
1953 bw, url, NULL, BW_NAVIGATE_HISTORY, NULL, NULL, NULL);
1954 nsurl_unref(url);
1955 }
1956 if (res != NSERROR_OK) {
1958 }
1959
1960 return TRUE;
1961}
1962
1963
1964/**
1965 * callback for url entry widget changing
1966 *
1967 * handler connected to url entry widget for the change signal
1968 *
1969 * \param widget The widget the signal is being delivered to.
1970 * \param event The key change event that changed the entry.
1971 * \param data The toolbar context passed when the signal was connected
1972 * \return TRUE to allow activation.
1973 */
1974static gboolean
1975url_entry_changed_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
1976{
1977 return nsgtk_completion_update(GTK_ENTRY(widget));
1978}
1979
1980
1981/**
1982 * callback for url entry widget icon button release
1983 *
1984 * handler connected to url entry widget for the icon release signal
1985 *
1986 * \param widget The widget the signal is being delivered to.
1987 * \param event The key change event that changed the entry.
1988 * \param data The toolbar context passed when the signal was connected
1989 * \return TRUE to allow activation.
1990 */
1991static void
1993 GtkEntryIconPosition icon_pos,
1994 GdkEvent *event,
1995 gpointer data)
1996{
1997 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
1998 struct browser_window *bw;
1999
2000 bw = tb->get_bw(tb->get_ctx);
2001
2003}
2004
2005
2006/**
2007 * handler for web search tool bar entry item activate signal
2008 *
2009 * handler connected to web search entry widget for the activate signal
2010 *
2011 * \todo make this user selectable to switch between opening in new
2012 * and navigating current window. Possibly improve core search_web interfaces
2013 *
2014 * \param widget The widget the signal is being delivered to.
2015 * \param data The toolbar context passed when the signal was connected
2016 * \return TRUE
2017 */
2018static gboolean websearch_entry_activate_cb(GtkWidget *widget, gpointer data)
2019{
2020 nserror res;
2021 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2022 struct browser_window *bw;
2023 nsurl *url;
2024
2025 res = search_web_omni(gtk_entry_get_text(GTK_ENTRY(widget)),
2027 &url);
2028 if (res == NSERROR_OK) {
2029 bw = tb->get_bw(tb->get_ctx);
2030
2033 url,
2034 NULL,
2035 bw,
2036 NULL);
2037 nsurl_unref(url);
2038 }
2039 if (res != NSERROR_OK) {
2041 }
2042
2043 return TRUE;
2044}
2045
2046/**
2047 * handler for web search tool bar item button press signal
2048 *
2049 * allows a click in the websearch entry field to clear the name of the
2050 * provider.
2051 *
2052 * \todo this does not work well, different behaviour wanted perhaps?
2053 *
2054 * \param widget The widget the signal is being delivered to.
2055 * \param data The toolbar context passed when the signal was connected
2056 * \return TRUE
2057 */
2058static gboolean
2060 GdkEventFocus *f,
2061 gpointer data)
2062{
2063 gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
2064 gtk_widget_grab_focus(GTK_WIDGET(widget));
2065
2066 return TRUE;
2067}
2068
2069
2070/**
2071 * handler for new window tool bar item clicked signal
2072 *
2073 * \param widget The widget the signal is being delivered to.
2074 * \param data The toolbar context passed when the signal was connected
2075 * \return TRUE
2076 */
2077static gboolean
2078newwindow_button_clicked_cb(GtkWidget *widget, gpointer data)
2079{
2080 nserror res;
2081 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2082
2083 res = nsgtk_browser_window_create(tb->get_bw(tb->get_ctx), false);
2084 if (res != NSERROR_OK) {
2086 }
2087
2088 return TRUE;
2089}
2090
2091
2092/**
2093 * handler for new tab tool bar item clicked signal
2094 *
2095 * \param widget The widget the signal is being delivered to.
2096 * \param data The toolbar context passed when the signal was connected
2097 * \return TRUE
2098 */
2099static gboolean
2100newtab_button_clicked_cb(GtkWidget *widget, gpointer data)
2101{
2102 nserror res;
2103 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2104
2105 res = nsgtk_browser_window_create(tb->get_bw(tb->get_ctx), true);
2106 if (res != NSERROR_OK) {
2108 }
2109 return TRUE;
2110}
2111
2112
2113/**
2114 * handler for open file tool bar item clicked signal
2115 *
2116 * \param widget The widget the signal is being delivered to.
2117 * \param data The toolbar context passed when the signal was connected
2118 * \return TRUE
2119 */
2120static gboolean
2121openfile_button_clicked_cb(GtkWidget *widget, gpointer data)
2122{
2123 GtkWidget *dlgOpen;
2124 gint response;
2125 GtkWidget *toplevel;
2126 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2127 struct browser_window *bw;
2128
2129 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2130
2131 dlgOpen = gtk_file_chooser_dialog_new("Open File",
2132 GTK_WINDOW(toplevel),
2133 GTK_FILE_CHOOSER_ACTION_OPEN,
2134 NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2135 NSGTK_STOCK_OPEN, GTK_RESPONSE_OK,
2136 NULL, NULL);
2137
2138 response = gtk_dialog_run(GTK_DIALOG(dlgOpen));
2139 if (response == GTK_RESPONSE_OK) {
2140 char *urltxt;
2141 gchar *filename;
2142 nserror res;
2143 nsurl *url;
2144
2145 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlgOpen));
2146
2147 urltxt = malloc(strlen(filename) + FILE_SCHEME_PREFIX_LEN + 1);
2148 if (urltxt != NULL) {
2149 sprintf(urltxt, FILE_SCHEME_PREFIX"%s", filename);
2150
2151 res = nsurl_create(urltxt, &url);
2152 if (res == NSERROR_OK) {
2153 bw = tb->get_bw(tb->get_ctx);
2155 url,
2156 NULL,
2158 NULL,
2159 NULL,
2160 NULL);
2161 nsurl_unref(url);
2162 }
2163 if (res != NSERROR_OK) {
2165 }
2166 free(urltxt);
2167 }
2168
2169
2170 g_free(filename);
2171 }
2172
2173 gtk_widget_destroy(dlgOpen);
2174
2175 return TRUE;
2176}
2177
2178
2179/**
2180 * handler for close window tool bar item clicked signal
2181 *
2182 * \param widget The widget the signal is being delivered to.
2183 * \param data The toolbar context passed when the signal was connected
2184 * \return TRUE
2185 */
2186static gboolean
2187closewindow_button_clicked_cb(GtkWidget *widget, gpointer data)
2188{
2189 GtkWidget *toplevel;
2190 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2191 gtk_widget_destroy(toplevel);
2192 return TRUE;
2193}
2194
2195
2196/**
2197 * handler for full save export tool bar item clicked signal
2198 *
2199 * \param widget The widget the signal is being delivered to.
2200 * \param data The toolbar context passed when the signal was connected
2201 * \return TRUE
2202 */
2203static gboolean
2204savepage_button_clicked_cb(GtkWidget *widget, gpointer data)
2205{
2206 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2207 struct browser_window *bw;
2208 DIR *d;
2209 gchar *path;
2210 nserror res;
2211 GtkWidget *toplevel;
2212
2213 bw = tb->get_bw(tb->get_ctx);
2214 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2215
2216 res = nsgtk_saveas_dialog(bw,
2217 messages_get("gtkcompleteSave"),
2218 GTK_WINDOW(toplevel),
2219 true,
2220 &path);
2221 if (res != NSERROR_OK) {
2222 return FALSE;
2223 }
2224
2225 d = opendir(path);
2226 if (d == NULL) {
2227 NSLOG(netsurf, INFO,
2228 "Unable to open directory %s for complete save: %s",
2229 path,
2230 strerror(errno));
2231 if (errno == ENOTDIR) {
2232 nsgtk_warning("NoDirError", path);
2233 } else {
2234 nsgtk_warning("gtkFileError", path);
2235 }
2236 g_free(path);
2237 return TRUE;
2238 }
2239 closedir(d);
2240
2242 g_free(path);
2243
2244 return TRUE;
2245}
2246
2247
2248/**
2249 * handler for pdf export tool bar item clicked signal
2250 *
2251 * \param widget The widget the signal is being delivered to.
2252 * \param data The toolbar context passed when the signal was connected
2253 * \return TRUE
2254 */
2255static gboolean
2256pdf_button_clicked_cb(GtkWidget *widget, gpointer data)
2257{
2258 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2259 struct browser_window *bw;
2260 GtkWidget *toplevel;
2261 gchar *filename;
2262 nserror res;
2263
2264 bw = tb->get_bw(tb->get_ctx);
2265
2266 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2267
2268 res = nsgtk_saveas_dialog(bw,
2269 "Export to PDF",
2270 GTK_WINDOW(toplevel),
2271 false,
2272 &filename);
2273 if (res != NSERROR_OK) {
2274 return FALSE;
2275 }
2276
2277#ifdef WITH_PDF_EXPORT
2278 struct print_settings *settings;
2279
2280 /* this way the scale used by PDF functions is synchronised with that
2281 * used by the all-purpose print interface
2282 */
2283 haru_nsfont_set_scale((float)option_export_scale / 100);
2284
2286 (const char *) filename,
2287 &haru_nsfont);
2288 g_free(filename);
2289 if (settings == NULL) {
2290 return TRUE;
2291 }
2292 /* This will clean up the print_settings object for us */
2294#endif
2295 return TRUE;
2296
2297}
2298
2299
2300/**
2301 * handler for plain text export tool bar item clicked signal
2302 *
2303 * \param widget The widget the signal is being delivered to.
2304 * \param data The toolbar context passed when the signal was connected
2305 * \return TRUE
2306 */
2307static gboolean
2308plaintext_button_clicked_cb(GtkWidget *widget, gpointer data)
2309{
2310 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2311 struct browser_window *bw;
2312 GtkWidget *toplevel;
2313 gchar *filename;
2314 nserror res;
2315
2316 bw = tb->get_bw(tb->get_ctx);
2317
2318 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2319
2320 res = nsgtk_saveas_dialog(bw,
2321 messages_get("gtkplainSave"),
2322 GTK_WINDOW(toplevel),
2323 false,
2324 &filename);
2325 if (res != NSERROR_OK) {
2326 return FALSE;
2327 }
2328
2329
2331 g_free(filename);
2332
2333 return TRUE;
2334}
2335
2336
2337/**
2338 * handler for print tool bar item clicked signal
2339 *
2340 * \param widget The widget the signal is being delivered to.
2341 * \param data The toolbar context passed when the signal was connected
2342 * \return TRUE
2343 */
2344static gboolean
2345print_button_clicked_cb(GtkWidget *widget, gpointer data)
2346{
2347 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2348 struct browser_window *bw;
2349 GtkPrintOperation *print_op;
2350 GtkPageSetup *page_setup;
2351 GtkPrintSettings *print_settings;
2352 GtkPrintOperationResult res = GTK_PRINT_OPERATION_RESULT_ERROR;
2353 struct print_settings *nssettings;
2354 char *settings_fname = NULL;
2355 GtkWidget *toplevel;
2356
2357 bw = tb->get_bw(tb->get_ctx);
2358
2359 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2360
2361 print_op = gtk_print_operation_new();
2362 if (print_op == NULL) {
2363 nsgtk_warning(messages_get("NoMemory"), 0);
2364 return TRUE;
2365 }
2366
2367 /* use previously saved settings if any */
2368 netsurf_mkpath(&settings_fname, NULL, 2, nsgtk_config_home, "Print");
2369 if (settings_fname != NULL) {
2370 print_settings = gtk_print_settings_new_from_file(settings_fname, NULL);
2371 if (print_settings != NULL) {
2372 gtk_print_operation_set_print_settings(print_op,
2374
2375 /* We're not interested in the settings any more */
2376 g_object_unref(print_settings);
2377 }
2378 }
2379
2381
2382 page_setup = gtk_print_run_page_setup_dialog(GTK_WINDOW(toplevel),
2383 NULL,
2384 NULL);
2385 if (page_setup == NULL) {
2386 nsgtk_warning(messages_get("NoMemory"), 0);
2387 free(settings_fname);
2388 g_object_unref(print_op);
2389 return TRUE;
2390 }
2391 gtk_print_operation_set_default_page_setup(print_op, page_setup);
2392
2394 NULL,
2396
2397 g_signal_connect(print_op,
2398 "begin_print",
2399 G_CALLBACK(gtk_print_signal_begin_print),
2400 nssettings);
2401 g_signal_connect(print_op,
2402 "draw_page",
2403 G_CALLBACK(gtk_print_signal_draw_page),
2404 NULL);
2405 g_signal_connect(print_op,
2406 "end_print",
2407 G_CALLBACK(gtk_print_signal_end_print),
2408 nssettings);
2409
2411 res = gtk_print_operation_run(print_op,
2412 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2413 GTK_WINDOW(toplevel),
2414 NULL);
2415 }
2416
2417 /* if the settings were used save them for future use */
2418 if (settings_fname != NULL) {
2419 if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
2420 /* Do not increment the settings reference */
2421 print_settings = gtk_print_operation_get_print_settings(print_op);
2422
2423 gtk_print_settings_to_file(print_settings,
2424 settings_fname,
2425 NULL);
2426 }
2427 free(settings_fname);
2428 }
2429
2430 /* Our print_settings object is destroyed by the end print handler */
2431 g_object_unref(page_setup);
2432 g_object_unref(print_op);
2433
2434 return TRUE;
2435}
2436
2437/**
2438 * handler for quit tool bar item clicked signal
2439 *
2440 * \param widget The widget the signal is being delivered to.
2441 * \param data The toolbar context passed when the signal was connected
2442 * \return TRUE
2443 */
2444static gboolean
2445quit_button_clicked_cb(GtkWidget *widget, gpointer data)
2446{
2448 return TRUE;
2449}
2450
2451
2452/**
2453 * handler for cut tool bar item clicked signal
2454 *
2455 * \param widget The widget the signal is being delivered to.
2456 * \param data The toolbar context passed when the signal was connected
2457 * \return TRUE
2458 */
2459static gboolean
2460cut_button_clicked_cb(GtkWidget *widget, gpointer data)
2461{
2462 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2463 struct browser_window *bw;
2464 GtkWidget *focused;
2465 GtkWidget *toplevel;
2466
2467 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2468
2469 focused = gtk_window_get_focus(GTK_WINDOW(toplevel));
2470
2471 /* let gtk handle it if focused widget is an editable */
2472 if (GTK_IS_EDITABLE(focused)) {
2473 gtk_editable_cut_clipboard(GTK_EDITABLE(focused));
2474 } else {
2475 bw = tb->get_bw(tb->get_ctx);
2477 }
2478
2479 return TRUE;
2480}
2481
2482
2483/**
2484 * handler for copy tool bar item clicked signal
2485 *
2486 * \param widget The widget the signal is being delivered to.
2487 * \param data The toolbar context passed when the signal was connected
2488 * \return TRUE
2489 */
2490static gboolean
2491copy_button_clicked_cb(GtkWidget *widget, gpointer data)
2492{
2493 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2494 struct browser_window *bw;
2495 GtkWidget *focused;
2496 GtkWidget *toplevel;
2497
2498 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2499
2500 focused = gtk_window_get_focus(GTK_WINDOW(toplevel));
2501
2502 /* let gtk handle it if focused widget is an editable */
2503 if (GTK_IS_EDITABLE(focused)) {
2504 gtk_editable_copy_clipboard(GTK_EDITABLE(focused));
2505 } else {
2506 bw = tb->get_bw(tb->get_ctx);
2508 }
2509
2510 return TRUE;
2511}
2512
2513
2514/**
2515 * handler for paste tool bar item clicked signal
2516 *
2517 * \param widget The widget the signal is being delivered to.
2518 * \param data The toolbar context passed when the signal was connected
2519 * \return TRUE
2520 */
2521static gboolean
2522paste_button_clicked_cb(GtkWidget *widget, gpointer data)
2523{
2524 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2525 struct browser_window *bw;
2526 GtkWidget *focused;
2527 GtkWidget *toplevel;
2528
2529 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2530
2531 focused = gtk_window_get_focus(GTK_WINDOW(toplevel));
2532
2533 /* let gtk handle it if focused widget is an editable */
2534 if (GTK_IS_EDITABLE(focused)) {
2535 gtk_editable_paste_clipboard(GTK_EDITABLE(focused));
2536 } else {
2537 bw = tb->get_bw(tb->get_ctx);
2539 }
2540
2541 return TRUE;
2542}
2543
2544
2545/**
2546 * handler for delete tool bar item clicked signal
2547 *
2548 * \param widget The widget the signal is being delivered to.
2549 * \param data The toolbar context passed when the signal was connected
2550 * \return TRUE
2551 */
2552static gboolean
2553delete_button_clicked_cb(GtkWidget *widget, gpointer data)
2554{
2555 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2556 struct browser_window *bw;
2557 GtkWidget *focused;
2558 GtkWidget *toplevel;
2559
2560 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2561
2562 focused = gtk_window_get_focus(GTK_WINDOW(toplevel));
2563
2564 /* let gtk handle it if focused widget is an editable */
2565 if (GTK_IS_EDITABLE(focused)) {
2566 gtk_editable_delete_selection(GTK_EDITABLE(focused));
2567 } else {
2568 bw = tb->get_bw(tb->get_ctx);
2570 }
2571
2572 return TRUE;
2573}
2574
2575
2576/**
2577 * handler for select all tool bar item clicked signal
2578 *
2579 * \param widget The widget the signal is being delivered to.
2580 * \param data The toolbar context passed when the signal was connected
2581 * \return TRUE
2582 */
2583static gboolean
2584selectall_button_clicked_cb(GtkWidget *widget, gpointer data)
2585{
2586 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2587 struct browser_window *bw;
2588 GtkWidget *focused;
2589 GtkWidget *toplevel;
2590
2591 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2592
2593 focused = gtk_window_get_focus(GTK_WINDOW(toplevel));
2594
2595 /* let gtk handle it if focused widget is an editable */
2596 if (GTK_IS_EDITABLE(focused)) {
2597 gtk_editable_select_region(GTK_EDITABLE(focused), 0, -1);
2598 } else {
2599 bw = tb->get_bw(tb->get_ctx);
2601 }
2602
2603 return TRUE;
2604}
2605
2606
2607/**
2608 * handler for preferences tool bar item clicked signal
2609 *
2610 * \param widget The widget the signal is being delivered to.
2611 * \param data The toolbar context passed when the signal was connected
2612 * \return TRUE
2613 */
2614static gboolean
2615preferences_button_clicked_cb(GtkWidget *widget, gpointer data)
2616{
2617 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2618 struct browser_window *bw;
2619 GtkWidget *toplevel;
2620 GtkWidget *wndpreferences;
2621
2622 bw = tb->get_bw(tb->get_ctx);
2623
2624 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2625
2626 wndpreferences = nsgtk_preferences(bw, GTK_WINDOW(toplevel));
2627 if (wndpreferences != NULL) {
2628 gtk_widget_show(wndpreferences);
2629 }
2630
2631 return TRUE;
2632}
2633
2634
2635/**
2636 * handler for zoom plus tool bar item clicked signal
2637 *
2638 * \param widget The widget the signal is being delivered to.
2639 * \param data The toolbar context passed when the signal was connected
2640 * \return TRUE
2641 */
2642static gboolean
2643zoomplus_button_clicked_cb(GtkWidget *widget, gpointer data)
2644{
2645 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2646 struct browser_window *bw;
2647
2648 bw = tb->get_bw(tb->get_ctx);
2649
2650 browser_window_set_scale(bw, 0.05, false);
2651
2652 return TRUE;
2653}
2654
2655
2656/**
2657 * handler for zoom minus tool bar item clicked signal
2658 *
2659 * \param widget The widget the signal is being delivered to.
2660 * \param data The toolbar context passed when the signal was connected
2661 * \return TRUE
2662 */
2663static gboolean
2664zoomminus_button_clicked_cb(GtkWidget *widget, gpointer data)
2665{
2666 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2667 struct browser_window *bw;
2668
2669 bw = tb->get_bw(tb->get_ctx);
2670
2671 browser_window_set_scale(bw, -0.05, false);
2672
2673 return TRUE;
2674
2675}
2676
2677
2678/**
2679 * handler for zoom normal tool bar item clicked signal
2680 *
2681 * \param widget The widget the signal is being delivered to.
2682 * \param data The toolbar context passed when the signal was connected
2683 * \return TRUE
2684 */
2685static gboolean
2686zoomnormal_button_clicked_cb(GtkWidget *widget, gpointer data)
2687{
2688 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2689 struct browser_window *bw;
2690
2691 bw = tb->get_bw(tb->get_ctx);
2692
2693 browser_window_set_scale(bw, 1.0, true);
2694
2695 return TRUE;
2696}
2697
2698
2699/**
2700 * handler for full screen tool bar item clicked signal
2701 *
2702 * \param widget The widget the signal is being delivered to.
2703 * \param data The toolbar context passed when the signal was connected
2704 * \return TRUE
2705 */
2706static gboolean
2707fullscreen_button_clicked_cb(GtkWidget *widget, gpointer data)
2708{
2709 GtkWindow *gtkwindow; /* gtk window widget is in */
2710 GdkWindow *gdkwindow;
2711 GdkWindowState state;
2712
2713 gtkwindow = GTK_WINDOW(gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW));
2714 gdkwindow = gtk_widget_get_window(GTK_WIDGET(gtkwindow));
2715 state = gdk_window_get_state(gdkwindow);
2716
2717 if (state & GDK_WINDOW_STATE_FULLSCREEN) {
2718 gtk_window_unfullscreen(gtkwindow);
2719 } else {
2720 gtk_window_fullscreen(gtkwindow);
2721 }
2722 return TRUE;
2723}
2724
2725
2726/**
2727 * handler for view source tool bar item clicked signal
2728 *
2729 * \param widget The widget the signal is being delivered to.
2730 * \param data The toolbar context passed when the signal was connected
2731 * \return TRUE
2732 */
2733static gboolean
2734viewsource_button_clicked_cb(GtkWidget *widget, gpointer data)
2735{
2736 nserror res;
2737 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2738 struct browser_window *bw;
2739 GtkWindow *gtkwindow; /* gtk window widget is in */
2740
2741 bw = tb->get_bw(tb->get_ctx);
2742
2743 gtkwindow = GTK_WINDOW(gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW));
2744
2745 res = nsgtk_viewsource(gtkwindow, bw);
2746 if (res != NSERROR_OK) {
2748 }
2749
2750 return TRUE;
2751}
2752
2753
2754/**
2755 * handler for show downloads tool bar item clicked signal
2756 *
2757 * \param widget The widget the signal is being delivered to.
2758 * \param data The toolbar context passed when the signal was connected
2759 * \return TRUE
2760 */
2761static gboolean
2762downloads_button_clicked_cb(GtkWidget *widget, gpointer data)
2763{
2764 GtkWindow *gtkwindow; /* gtk window widget is in */
2765 gtkwindow = GTK_WINDOW(gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW));
2766 nsgtk_download_show(gtkwindow);
2767 return TRUE;
2768}
2769
2770
2771/**
2772 * handler for show downloads tool bar item clicked signal
2773 *
2774 * \param widget The widget the signal is being delivered to.
2775 * \param data The toolbar context passed when the signal was connected
2776 * \return TRUE
2777 */
2778static gboolean
2779savewindowsize_button_clicked_cb(GtkWidget *widget, gpointer data)
2780{
2781 GtkWindow *gtkwindow; /* gtk window widget is in */
2782 int x,y,w,h;
2783 char *choices = NULL;
2784
2785 gtkwindow = GTK_WINDOW(gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW));
2786
2787 gtk_window_get_position(gtkwindow, &x, &y);
2788 gtk_window_get_size(gtkwindow, &w, &h);
2789
2790 nsoption_set_int(window_width, w);
2791 nsoption_set_int(window_height, h);
2792 nsoption_set_int(window_x, x);
2793 nsoption_set_int(window_y, y);
2794
2795 netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
2796 if (choices != NULL) {
2797 nsoption_write(choices, NULL, NULL);
2798 free(choices);
2799 }
2800
2801 return TRUE;
2802}
2803
2804
2805/**
2806 * handler for show downloads tool bar item clicked signal
2807 *
2808 * \param widget The widget the signal is being delivered to.
2809 * \param data The toolbar context passed when the signal was connected
2810 * \return TRUE
2811 */
2812static gboolean
2813toggledebugging_button_clicked_cb(GtkWidget *widget, gpointer data)
2814{
2815 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2816 struct browser_window *bw;
2817
2818 bw = tb->get_bw(tb->get_ctx);
2819
2821
2823
2824 return TRUE;
2825}
2826
2827
2828/**
2829 * handler for debug box tree tool bar item clicked signal
2830 *
2831 * \param widget The widget the signal is being delivered to.
2832 * \param data The toolbar context passed when the signal was connected
2833 * \return TRUE
2834 */
2835static gboolean
2836debugboxtree_button_clicked_cb(GtkWidget *widget, gpointer data)
2837{
2838 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2839 struct browser_window *bw;
2840 gchar *fname;
2841 gint handle;
2842 FILE *f;
2843
2844 handle = g_file_open_tmp("nsgtkboxtreeXXXXXX", &fname, NULL);
2845 if ((handle == -1) || (fname == NULL)) {
2846 return TRUE;
2847 }
2848 close(handle); /* in case it was binary mode */
2849
2850 /* save data to temporary file */
2851 f = fopen(fname, "w");
2852 if (f == NULL) {
2853 nsgtk_warning("Error saving box tree dump.",
2854 "Unable to open file for writing.");
2855 unlink(fname);
2856 return TRUE;
2857 }
2858
2859 bw = tb->get_bw(tb->get_ctx);
2860
2862
2863 fclose(f);
2864
2865 nsgtk_viewfile("Box Tree Debug", "boxtree", fname);
2866
2867 g_free(fname);
2868
2869 return TRUE;
2870}
2871
2872
2873/**
2874 * handler for debug dom tree tool bar item clicked signal
2875 *
2876 * \param widget The widget the signal is being delivered to.
2877 * \param data The toolbar context passed when the signal was connected
2878 * \return TRUE
2879 */
2880static gboolean
2881debugdomtree_button_clicked_cb(GtkWidget *widget, gpointer data)
2882{
2883 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2884 struct browser_window *bw;
2885 gchar *fname;
2886 gint handle;
2887 FILE *f;
2888
2889 handle = g_file_open_tmp("nsgtkdomtreeXXXXXX", &fname, NULL);
2890 if ((handle == -1) || (fname == NULL)) {
2891 return TRUE;
2892 }
2893 close(handle); /* in case it was binary mode */
2894
2895 /* save data to temporary file */
2896 f = fopen(fname, "w");
2897 if (f == NULL) {
2898 nsgtk_warning("Error saving box tree dump.",
2899 "Unable to open file for writing.");
2900 unlink(fname);
2901 return TRUE;
2902 }
2903
2904 bw = tb->get_bw(tb->get_ctx);
2905
2907
2908 fclose(f);
2909
2910 nsgtk_viewfile("DOM Tree Debug", "domtree", fname);
2911
2912 g_free(fname);
2913
2914 return TRUE;
2915
2916}
2917
2918
2919/**
2920 * handler for local history tool bar item clicked signal
2921 *
2922 * \param widget The widget the signal is being delivered to.
2923 * \param data The toolbar context passed when the signal was connected
2924 * \return TRUE
2925 */
2926static gboolean
2927localhistory_button_clicked_cb(GtkWidget *widget, gpointer data)
2928{
2929 nserror res;
2930 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2931 struct browser_window *bw;
2932 GtkWidget *toplevel;
2933
2934 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2935 if (toplevel != NULL) {
2936 bw = tb->get_bw(tb->get_ctx);
2937
2938 res = nsgtk_local_history_present(GTK_WINDOW(toplevel), bw);
2939 if (res != NSERROR_OK) {
2940 NSLOG(netsurf, INFO,
2941 "Unable to present local history window.");
2942 }
2943 }
2944 return TRUE;
2945}
2946
2947/**
2948 * handler for history tool bar item clicked signal
2949 *
2950 * \param widget The widget the signal is being delivered to.
2951 * \param data The toolbar context passed when the signal was connected
2952 * \return TRUE
2953 */
2954static gboolean
2955history_button_clicked_cb(GtkWidget *widget, gpointer data)
2956{
2957 return localhistory_button_clicked_cb(widget, data);
2958}
2959
2960
2961/**
2962 * handler for global history tool bar item clicked signal
2963 *
2964 * \param widget The widget the signal is being delivered to.
2965 * \param data The toolbar context passed when the signal was connected
2966 * \return TRUE
2967 */
2968static gboolean
2969globalhistory_button_clicked_cb(GtkWidget *widget, gpointer data)
2970{
2971 nserror res;
2973 if (res != NSERROR_OK) {
2974 NSLOG(netsurf, INFO,
2975 "Unable to initialise global history window.");
2976 }
2977 return TRUE;
2978}
2979
2980
2981/**
2982 * handler for add bookmark tool bar item clicked signal
2983 *
2984 * \param widget The widget the signal is being delivered to.
2985 * \param data The toolbar context passed when the signal was connected
2986 * \return TRUE
2987 */
2988static gboolean
2989addbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
2990{
2991 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2992 struct browser_window *bw;
2993
2994 bw = tb->get_bw(tb->get_ctx);
2997 }
2998 return TRUE;
2999}
3000
3001
3002/**
3003 * handler for show bookmark tool bar item clicked signal
3004 *
3005 * \param widget The widget the signal is being delivered to.
3006 * \param data The toolbar context passed when the signal was connected
3007 * \return TRUE
3008 */
3009static gboolean
3010showbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
3011{
3012 nserror res;
3013 res = nsgtk_hotlist_present();
3014 if (res != NSERROR_OK) {
3015 NSLOG(netsurf, INFO, "Unable to initialise bookmark window.");
3016 }
3017 return TRUE;
3018}
3019
3020
3021/**
3022 * handler for show cookies tool bar item clicked signal
3023 *
3024 * \param widget The widget the signal is being delivered to.
3025 * \param data The toolbar context passed when the signal was connected
3026 * \return TRUE
3027 */
3028static gboolean
3029showcookies_button_clicked_cb(GtkWidget *widget, gpointer data)
3030{
3031 nserror res;
3032 res = nsgtk_cookies_present(NULL);
3033 if (res != NSERROR_OK) {
3034 NSLOG(netsurf, INFO, "Unable to initialise cookies window.");
3035 }
3036 return TRUE;
3037}
3038
3039
3040/**
3041 * handler for open location tool bar item clicked signal
3042 *
3043 * \param widget The widget the signal is being delivered to.
3044 * \param data The toolbar context passed when the signal was connected
3045 * \return TRUE
3046 */
3047static gboolean
3048openlocation_button_clicked_cb(GtkWidget *widget, gpointer data)
3049{
3050 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3051 GtkToolItem *urltitem;
3052
3053 urltitem = tb->items[URL_BAR_ITEM].button;
3054 if (urltitem != NULL) {
3055 GtkEntry *entry;
3056 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(urltitem)));
3057 gtk_widget_grab_focus(GTK_WIDGET(entry));
3058 }
3059 return TRUE;
3060}
3061
3062
3063/**
3064 * handler for contents tool bar item clicked signal
3065 *
3066 * \param widget The widget the signal is being delivered to.
3067 * \param data The toolbar context passed when the signal was connected
3068 * \return TRUE
3069 */
3070static gboolean
3071contents_button_clicked_cb(GtkWidget *widget, gpointer data)
3072{
3073 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3074 nserror res;
3075
3076 res = toolbar_navigate_to_url(tb, "https://www.netsurf-browser.org/documentation/");
3077 if (res != NSERROR_OK) {
3079 }
3080
3081 return TRUE;
3082}
3083
3084/**
3085 * handler for contents tool bar item clicked signal
3086 *
3087 * \param widget The widget the signal is being delivered to.
3088 * \param data The toolbar context passed when the signal was connected
3089 * \return TRUE
3090 */
3091static gboolean
3092guide_button_clicked_cb(GtkWidget *widget, gpointer data)
3093{
3094 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3095 nserror res;
3096
3097 res = toolbar_navigate_to_url(tb, "https://www.netsurf-browser.org/documentation/guide");
3098 if (res != NSERROR_OK) {
3100 }
3101
3102 return TRUE;
3103}
3104
3105
3106/**
3107 * handler for contents tool bar item clicked signal
3108 *
3109 * \param widget The widget the signal is being delivered to.
3110 * \param data The toolbar context passed when the signal was connected
3111 * \return TRUE
3112 */
3113static gboolean
3114info_button_clicked_cb(GtkWidget *widget, gpointer data)
3115{
3116 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3117 nserror res;
3118
3119 res = toolbar_navigate_to_url(tb, "https://www.netsurf-browser.org/documentation/info");
3120 if (res != NSERROR_OK) {
3122 }
3123
3124 return TRUE;
3125}
3126
3127
3128/**
3129 * handler for contents tool bar item clicked signal
3130 *
3131 * \param widget The widget the signal is being delivered to.
3132 * \param data The toolbar context passed when the signal was connected
3133 * \return TRUE
3134 */
3135static gboolean about_button_clicked_cb(GtkWidget *widget, gpointer data)
3136{
3137 GtkWindow *parent; /* gtk window widget is in */
3138
3139 parent = GTK_WINDOW(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW));
3140
3142 return TRUE;
3143}
3144
3145/**
3146 * handler for openmenu tool bar item clicked signal
3147 *
3148 * \param widget The widget the signal is being delivered to.
3149 * \param data The toolbar context passed when the signal was connected
3150 * \return TRUE to indicate signal handled.
3151 */
3152static gboolean openmenu_button_clicked_cb(GtkWidget *widget, gpointer data)
3153{
3154 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3155 struct gui_window *gw;
3156 struct nsgtk_scaffolding *gs;
3157
3158 gw = tb->get_ctx; /** \todo stop assuming the context is a gui window */
3159
3160 gs = nsgtk_get_scaffold(gw);
3161
3163
3164 return TRUE;
3165}
3166
3167
3168/* define data plus and data minus handlers */
3169#define TOOLBAR_ITEM(identifier, name, snstvty, clicked, activate, label, iconame) \
3170static gboolean \
3171nsgtk_toolbar_##name##_data_plus(GtkWidget *widget, \
3172 GdkDragContext *cont, \
3173 GtkSelectionData *selection, \
3174 guint info, \
3175 guint time, \
3176 gpointer data) \
3177{ \
3178 struct nsgtk_toolbar_customisation *tbc; \
3179 tbc = (struct nsgtk_toolbar_customisation *)data; \
3180 tbc->dragitem = identifier; \
3181 tbc->dragfrom = true; \
3182 return TRUE; \
3183} \
3184static gboolean \
3185nsgtk_toolbar_##name##_data_minus(GtkWidget *widget, \
3186 GdkDragContext *cont, \
3187 GtkSelectionData *selection, \
3188 guint info, \
3189 guint time, \
3190 gpointer data) \
3191{ \
3192 struct nsgtk_toolbar_customisation *tbc; \
3193 tbc = (struct nsgtk_toolbar_customisation *)data; \
3194 tbc->dragitem = identifier; \
3195 tbc->dragfrom = false; \
3196 return TRUE; \
3197}
3198
3199#include "gtk/toolbar_items.h"
3200
3201#undef TOOLBAR_ITEM
3202
3203
3204/**
3205 * create a toolbar item
3206 *
3207 * create a toolbar item and set up its default handlers
3208 */
3209static nserror
3211{
3213
3214 /* set item defaults from macro */
3215 switch (id) {
3216#define TOOLBAR_ITEM_t(name) \
3217 item->clicked = name##_button_clicked_cb;
3218#define TOOLBAR_ITEM_b(name) \
3219 item->clicked = name##_button_clicked_cb;
3220#define TOOLBAR_ITEM_y(name) \
3221 item->clicked = name##_button_clicked_cb;
3222#define TOOLBAR_ITEM_n(name) \
3223 item->clicked = NULL;
3224#define TOOLBAR_ITEM(identifier, iname, snstvty, clicked, activate, label, iconame) \
3225 case identifier: \
3226 item->name = #iname; \
3227 item->sensitivity = snstvty; \
3228 item->dataplus = nsgtk_toolbar_##iname##_data_plus; \
3229 item->dataminus = nsgtk_toolbar_##iname##_data_minus; \
3230 TOOLBAR_ITEM_ ## clicked(iname) \
3231 break;
3232
3233#include "gtk/toolbar_items.h"
3234
3235#undef TOOLBAR_ITEM_t
3236#undef TOOLBAR_ITEM_y
3237#undef TOOLBAR_ITEM_n
3238#undef TOOLBAR_ITEM
3239
3240 case PLACEHOLDER_BUTTON:
3241 return NSERROR_INVALID;
3242 }
3243
3244 return NSERROR_OK;
3245}
3246
3247
3248/**
3249 * set a toolbar item to a throbber frame number
3250 *
3251 * \param toolbar_item The toolbar item to update
3252 * \param frame The animation frame number to update to
3253 * \return NSERROR_OK on success,
3254 * NSERROR_INVALID if the toolbar item does not contain an image,
3255 * NSERROR_BAD_SIZE if the frame is out of range.
3256 */
3257static nserror set_throbber_frame(GtkToolItem *toolbar_item, int frame)
3258{
3259 nserror res;
3260 GdkPixbuf *pixbuf;
3261 GtkImage *throbber;
3262
3263 if (toolbar_item == NULL) {
3264 /* no toolbar item */
3265 return NSERROR_INVALID;
3266 }
3267
3268 res = nsgtk_throbber_get_frame(frame, &pixbuf);
3269 if (res != NSERROR_OK) {
3270 return res;
3271 }
3272
3273 throbber = GTK_IMAGE(gtk_bin_get_child(GTK_BIN(toolbar_item)));
3274
3275 gtk_image_set_from_pixbuf(throbber, pixbuf);
3276
3277 return NSERROR_OK;
3278}
3279
3280
3281/**
3282 * Make the throbber run.
3283 *
3284 * scheduled callback to update the throbber
3285 *
3286 * \param p The context passed when scheduled.
3287 */
3288static void next_throbber_frame(void *p)
3289{
3290 struct nsgtk_toolbar *tb = p;
3291 nserror res;
3292
3293 tb->throb_frame++; /* advance to next frame */
3294
3296 tb->throb_frame);
3297 if (res == NSERROR_BAD_SIZE) {
3298 tb->throb_frame = 1;
3300 tb->throb_frame);
3301 }
3302
3303 /* only schedule next frame if there are no errors */
3304 if (res == NSERROR_OK) {
3306 }
3307}
3308
3309
3310/**
3311 * connect signal handlers to a gtk toolbar item
3312 */
3313static nserror
3315{
3316 struct nsgtk_toolbar_item *item;
3317 GtkEntry *entry;
3318
3319 item = &tb->items[itemid];
3320
3321 if (item->button != NULL) {
3322 g_signal_connect(item->button,
3323 "size-allocate",
3325 tb);
3326 }
3327
3328 switch (itemid) {
3329 case URL_BAR_ITEM:
3330 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(item->button)));
3331
3332 g_signal_connect(GTK_WIDGET(entry),
3333 "activate",
3334 G_CALLBACK(url_entry_activate_cb),
3335 tb);
3336 g_signal_connect(GTK_WIDGET(entry),
3337 "changed",
3338 G_CALLBACK(url_entry_changed_cb),
3339 tb);
3340 g_signal_connect(GTK_WIDGET(entry),
3341 "icon-release",
3342 G_CALLBACK(url_entry_icon_release_cb),
3343 tb);
3344
3346 tb->get_bw,
3347 tb->get_ctx);
3348 break;
3349
3350
3351 case WEBSEARCH_ITEM:
3352 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(item->button)));
3353
3354 g_signal_connect(GTK_WIDGET(entry),
3355 "activate",
3356 G_CALLBACK(websearch_entry_activate_cb),
3357 tb);
3358 g_signal_connect(GTK_WIDGET(entry),
3359 "button-press-event",
3361 tb);
3362 break;
3363
3364 default:
3365 if ((item->clicked != NULL) && (item->button != NULL)) {
3366 g_signal_connect(item->button,
3367 "clicked",
3368 G_CALLBACK(item->clicked),
3369 tb);
3370 }
3371 break;
3372
3373 }
3374
3375 return NSERROR_OK;
3376}
3377
3378/**
3379 * connect all signals to widgets in a toolbar
3380 */
3382{
3383 int location; /* location index */
3384 nsgtk_toolbar_button itemid; /* item id */
3385
3387 itemid = itemid_from_location(tb, location);
3388 if (itemid == PLACEHOLDER_BUTTON) {
3389 /* no more filled locations */
3390 break;
3391 }
3392 toolbar_connect_signal(tb, itemid);
3393 }
3394
3395 return NSERROR_OK;
3396}
3397
3398
3399/**
3400 * signal handler for toolbar context menu
3401 *
3402 * \param toolbar The toolbar event is being delivered to
3403 * \param x The x coordinate where the click happened
3404 * \param y The x coordinate where the click happened
3405 * \param button the buttons being pressed
3406 * \param data The context pointer passed when the connection was made.
3407 * \return TRUE to indicate signal handled.
3408 */
3409static gboolean
3411 gint x,
3412 gint y,
3413 gint button,
3414 gpointer data)
3415{
3416 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3417 struct gui_window *gw;
3418 struct nsgtk_scaffolding *gs;
3419
3420 gw = tb->get_ctx; /** \todo stop assuming the context is a gui window */
3421
3422 gs = nsgtk_get_scaffold(gw);
3423
3425
3426 return TRUE;
3427}
3428
3429
3430/**
3431 * toolbar delete signal handler
3432 */
3433static void toolbar_destroy_cb(GtkWidget *widget, gpointer data)
3434{
3435 struct nsgtk_toolbar *tb;
3436 tb = (struct nsgtk_toolbar *)data;
3437
3438 /* ensure any throbber scheduled is stopped */
3440
3441 free(tb);
3442}
3443
3444
3445/* exported interface documented in toolbar.h */
3446nserror
3447nsgtk_toolbar_create(GtkBuilder *builder,
3448 struct browser_window *(*get_bw)(void *ctx),
3449 void *get_ctx,
3450 bool want_location_focus,
3451 struct nsgtk_toolbar **tb_out)
3452{
3453 nserror res;
3454 struct nsgtk_toolbar *tb;
3455 int bidx; /* button index */
3456
3457 tb = calloc(1, sizeof(struct nsgtk_toolbar));
3458 if (tb == NULL) {
3459 return NSERROR_NOMEM;
3460 }
3461
3462 tb->get_bw = get_bw;
3463 tb->get_ctx = get_ctx;
3464 /* set the throbber start frame. */
3465 tb->throb_frame = 0;
3466 if (want_location_focus) {
3467 tb->loc_focus = LFS_WANT;
3468 } else {
3469 tb->loc_focus = LFS_IDLE;
3470 }
3471
3472 tb->widget = GTK_TOOLBAR(gtk_builder_get_object(builder, "toolbar"));
3473 gtk_toolbar_set_show_arrow(tb->widget, TRUE);
3474
3475 g_signal_connect(tb->widget,
3476 "popup-context-menu",
3478 tb);
3479
3480 /* close and cleanup on delete signal */
3481 g_signal_connect(tb->widget,
3482 "destroy",
3483 G_CALLBACK(toolbar_destroy_cb),
3484 tb);
3485
3486 /* allocate button contexts */
3487 for (bidx = BACK_BUTTON; bidx < PLACEHOLDER_BUTTON; bidx++) {
3488 res = toolbar_item_create(bidx, &tb->items[bidx]);
3489 if (res != NSERROR_OK) {
3490 return res;
3491 }
3492 }
3493
3494 res = nsgtk_toolbar_update(tb);
3495 if (res != NSERROR_OK) {
3496 return res;
3497 }
3498
3499 *tb_out = tb;
3500 return NSERROR_OK;
3501}
3502
3503
3504/* exported interface documented in toolbar.h */
3506{
3507 /*
3508 * reset toolbar size allocation so icon size change affects
3509 * allocated widths.
3510 */
3511 tb->offset = 0;
3512
3513 switch (nsoption_int(button_type)) {
3514
3515 case 1: /* Small icons */
3516 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3517 GTK_TOOLBAR_ICONS);
3518 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb->widget),
3519 GTK_ICON_SIZE_SMALL_TOOLBAR);
3520 break;
3521
3522 case 2: /* Large icons */
3523 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3524 GTK_TOOLBAR_ICONS);
3525 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb->widget),
3526 GTK_ICON_SIZE_LARGE_TOOLBAR);
3527 break;
3528
3529 case 3: /* Large icons with text */
3530 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3531 GTK_TOOLBAR_BOTH);
3532 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb->widget),
3533 GTK_ICON_SIZE_LARGE_TOOLBAR);
3534 break;
3535
3536 case 4: /* Text icons only */
3537 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3538 GTK_TOOLBAR_TEXT);
3539 break;
3540
3541 default:
3542 break;
3543 }
3544
3545 return NSERROR_OK;
3546}
3547
3548
3549/* exported interface documented in toolbar.h */
3551{
3552 nserror res;
3553 struct browser_window *bw;
3554
3555 /* Manage the location focus state */
3556 switch (tb->loc_focus) {
3557 case LFS_IDLE:
3558 break;
3559 case LFS_WANT:
3560 if (active) {
3561 tb->loc_focus = LFS_THROB;
3562 }
3563 break;
3564 case LFS_THROB:
3565 if (!active) {
3566 tb->loc_focus = LFS_LAST;
3567 }
3568 break;
3569 case LFS_LAST:
3570 break;
3571 }
3572
3573 /* when activating the throbber simply schedule the next frame update */
3574 if (active) {
3576
3580
3581 return NSERROR_OK;
3582 }
3583
3584 /* stopping the throbber */
3586 tb->throb_frame = 0;
3588 tb->throb_frame);
3589
3590 bw = tb->get_bw(tb->get_ctx);
3591
3592 /* adjust sensitivity of other items */
3601
3602 return res;
3603}
3604
3605
3606/* exported interface documented in toolbar.h */
3608{
3609 GtkEntry *url_entry;
3611 struct browser_window *bw;
3612 const char *icon_name;
3613
3614 if (tb->items[URL_BAR_ITEM].button == NULL) {
3615 /* no toolbar item */
3616 return NSERROR_INVALID;
3617 }
3618 url_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(tb->items[URL_BAR_ITEM].button)));
3619
3620 bw = tb->get_bw(tb->get_ctx);
3621
3623
3624 switch (pistate) {
3626 icon_name = "page-info-internal";
3627 break;
3628
3629 case PAGE_STATE_LOCAL:
3630 icon_name = "page-info-local";
3631 break;
3632
3634 icon_name = "page-info-insecure";
3635 break;
3636
3638 icon_name = "page-info-warning";
3639 break;
3640
3642 icon_name = "page-info-warning";
3643 break;
3644
3645 case PAGE_STATE_SECURE:
3646 icon_name = "page-info-secure";
3647 break;
3648
3649 default:
3650 icon_name = "page-info-internal";
3651 break;
3652 }
3653
3654 nsgtk_entry_set_icon_from_icon_name(GTK_WIDGET(url_entry),
3656 icon_name);
3657 return NSERROR_OK;
3658}
3659
3660
3661/* exported interface documented in toolbar.h */
3663{
3664 size_t idn_url_l;
3665 char *idn_url_s = NULL;
3666 const char *url_text = NULL;
3667 GtkEntry *url_entry;
3668
3669 if (tb->items[URL_BAR_ITEM].button == NULL) {
3670 /* no toolbar item */
3671 return NSERROR_INVALID;
3672 }
3673 url_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(tb->items[URL_BAR_ITEM].button)));
3674
3675 if (nsoption_bool(display_decoded_idn) == true) {
3676 if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK) {
3677 idn_url_s = NULL;
3678 }
3679 url_text = idn_url_s;
3680 }
3681 if (url_text == NULL) {
3682 url_text = nsurl_access(url);
3683 }
3684
3685 if (strcmp(url_text, gtk_entry_get_text(url_entry)) != 0) {
3686 /* The URL bar content has changed, we need to update it */
3687 gint startpos, endpos;
3688 bool was_selected;
3689 gtk_editable_get_selection_bounds(GTK_EDITABLE(url_entry),
3690 &startpos, &endpos);
3691 was_selected = gtk_widget_is_focus(GTK_WIDGET(url_entry)) &&
3692 startpos == 0 &&
3693 endpos == gtk_entry_get_text_length(url_entry);
3694 gtk_entry_set_text(url_entry, url_text);
3695 if (was_selected && tb->loc_focus != LFS_IDLE) {
3696 gtk_widget_grab_focus(GTK_WIDGET(url_entry));
3697 if (tb->loc_focus == LFS_LAST) {
3698 tb->loc_focus = LFS_IDLE;
3699 }
3700 }
3701 }
3702
3703 if (idn_url_s != NULL) {
3704 free(idn_url_s);
3705 }
3706
3707 return NSERROR_OK;
3708}
3709
3710
3711/* exported interface documented in toolbar.h */
3712nserror
3714{
3715 GtkWidget *entry;
3716
3717 if (tb->items[WEBSEARCH_ITEM].button == NULL) {
3718 /* no toolbar item */
3719 return NSERROR_INVALID;
3720 }
3721
3722 entry = gtk_bin_get_child(GTK_BIN(tb->items[WEBSEARCH_ITEM].button));
3723
3724 if (pixbuf != NULL) {
3727 pixbuf);
3728 } else {
3732 }
3733
3734 return NSERROR_OK;
3735}
3736
3737
3738/* exported interface documented in toolbar.h */
3739nserror
3741 nsgtk_toolbar_button itemid)
3742{
3743 GtkWidget *widget;
3744
3745 /* ensure item id in range */
3746 if ((itemid < BACK_BUTTON) || (itemid >= PLACEHOLDER_BUTTON)) {
3747 return NSERROR_BAD_PARAMETER;
3748 }
3749
3750 if (tb->items[itemid].clicked == NULL) {
3751 return NSERROR_INVALID;
3752 }
3753
3754 /*
3755 * if item has a widget in the current toolbar use that as the
3756 * signal source otherwise use the toolbar widget itself.
3757 */
3758 if (tb->items[itemid].button != NULL) {
3759 widget = GTK_WIDGET(tb->items[itemid].button);
3760 } else {
3761 widget = GTK_WIDGET(tb->widget);
3762 }
3763
3764 tb->items[itemid].clicked(widget, tb);
3765
3766 return NSERROR_OK;
3767}
3768
3769
3770/* exported interface documented in toolbar.h */
3772{
3773 if (show) {
3774 gtk_widget_show(GTK_WIDGET(tb->widget));
3775 } else {
3776 gtk_widget_hide(GTK_WIDGET(tb->widget));
3777 }
3778 return NSERROR_OK;
3779}
3780
3781
3782/* exported interface documented in toolbar.h */
3784{
3785 nserror res;
3786
3787 /* setup item locations based on user config */
3789 if (res != NSERROR_OK) {
3790 return res;
3791 }
3792
3793 /* populate toolbar widget */
3795 if (res != NSERROR_OK) {
3796 return res;
3797 }
3798
3799 /* ensure icon sizes and text labels on toolbar are set */
3800 res = nsgtk_toolbar_restyle(tb);
3801 if (res != NSERROR_OK) {
3802 return res;
3803 }
3804
3805 res = toolbar_connect_signals(tb);
3806
3807 return res;
3808}
3809
3810/**
3811 * Find the correct location for popping up a window for the chosen item.
3812 *
3813 * \param tb The toolbar to select from
3814 * \param item_idx The toolbar item to select from
3815 * \param out_x Filled with an appropriate X coordinate
3816 * \param out_y Filled with an appropriate Y coordinate
3817 */
3818static nserror
3820 int item_idx,
3821 int *out_x,
3822 int *out_y)
3823{
3824 struct nsgtk_toolbar_item *item = &tb->items[item_idx];
3825 GtkWidget *widget = GTK_WIDGET(item->button);
3826 GtkAllocation alloc;
3827 gint rootx, rooty, x, y;
3828
3829 switch (item_idx) {
3830 case URL_BAR_ITEM:
3831 widget = GTK_WIDGET(gtk_bin_get_child(GTK_BIN(item->button)));
3832 break;
3833 default:
3834 /* Nothing to do here */
3835 break;
3836 }
3837
3838 nsgtk_widget_get_allocation(widget, &alloc);
3839
3840 if (gtk_widget_translate_coordinates(widget,
3841 gtk_widget_get_toplevel(widget),
3842 0,
3843 alloc.height - 1,
3844 &x, &y) != TRUE) {
3845 return NSERROR_UNKNOWN;
3846 }
3847
3848 gtk_window_get_position(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
3849 &rootx, &rooty);
3850
3851 *out_x = rootx + x + 4;
3852 *out_y = rooty + y + 4;
3853
3854 return NSERROR_OK;
3855}
3856
3858 struct nsgtk_pi_window *win)
3859{
3860 nserror res;
3861 int x, y;
3862
3864 if (res != NSERROR_OK) {
3865 return res;
3866 }
3867
3869
3870 return NSERROR_OK;
3871}
3872
3873/* exported interface documented in toolbar.h */
3875{
3876 nserror res;
3877 int x, y;
3878
3880 if (res != NSERROR_OK) {
3881 return res;
3882 }
3883
3885
3886 return NSERROR_OK;
3887}
static struct BitMap * throbber
Definition: theme.c:55
nserror browser_window_history_forward(struct browser_window *bw, bool new_window)
Go forward in the history.
bool browser_window_history_forward_available(struct browser_window *bw)
Check whether it is pssible to go forwards in the history.
bool browser_window_history_back_available(struct browser_window *bw)
Check whether it is pssible to go back in the history.
nserror browser_window_history_back(struct browser_window *bw, bool new_window)
Go back in the history.
Interface to browser history operations.
Browser window creation and manipulation interface.
nserror browser_window_navigate(struct browser_window *bw, struct nsurl *url, struct nsurl *referrer, enum browser_window_nav_flags flags, char *post_urlenc, struct fetch_multipart_data *post_multipart, struct hlcache_handle *parent)
Start fetching a page in a browser window.
bool browser_window_has_content(struct browser_window *bw)
Find out if a browser window is currently showing a content.
nserror browser_window_debug(struct browser_window *bw, enum content_debug op)
Set debug options on a window.
nserror browser_window_reload(struct browser_window *bw, bool all)
Reload the page in a browser window.
struct nsurl * browser_window_access_url(const struct browser_window *bw)
Access a browser window's URL.
browser_window_page_info_state
Browser window page information states.
@ PAGE_STATE_INSECURE
Insecure page load.
@ PAGE_STATE_SECURE_ISSUES
Secure load, but has insecure elements.
@ PAGE_STATE_SECURE
Secure load.
@ PAGE_STATE_SECURE_OVERRIDE
Secure load, but had to override.
@ PAGE_STATE_LOCAL
Page loaded from file:/// etc.
@ PAGE_STATE_INTERNAL
Page loaded from internal handler.
nserror browser_window_create(enum browser_window_create_flags flags, struct nsurl *url, struct nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
void browser_window_stop(struct browser_window *bw)
Stop all fetching activity in a browser window.
nserror browser_window_set_scale(struct browser_window *bw, float scale, bool absolute)
Sets the scale of a browser window.
browser_window_page_info_state browser_window_get_page_info_state(const struct browser_window *bw)
Request the current browser window page info state.
struct hlcache_handle * browser_window_get_content(struct browser_window *bw)
Get a cache handle for the content within a browser window.
nserror browser_window_debug_dump(struct browser_window *bw, FILE *f, enum content_debug op)
Dump debug info concerning the browser window's contents to file.
@ BW_CREATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
@ BW_CREATE_TAB
New gui_window to be tab in same window as "existing" gui_window.
@ BW_CREATE_FOREGROUND
Request foreground opening.
@ BW_CREATE_FOCUS_LOCATION
Request location bar focus.
@ BW_NAVIGATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
void nsgtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation)
Definition: compat.c:489
void nsgtk_widget_set_margins(GtkWidget *widget, gint hmargin, gint vmargin)
Set the margins of a widget.
Definition: compat.c:625
void nsgtk_entry_set_icon_from_pixbuf(GtkWidget *entry, GtkEntryIconPosition icon_pos, GdkPixbuf *pixbuf)
Definition: compat.c:151
void nsgtk_widget_set_alignment(GtkWidget *widget, GtkAlign halign, GtkAlign valign)
Set the alignment of a widget.
Definition: compat.c:585
void nsgtk_entry_set_icon_from_icon_name(GtkWidget *entry, GtkEntryIconPosition icon_pos, const gchar *id)
Sets the icon shown in the entry at the specified position from an icon name.
Definition: compat.c:173
GtkWidget * nsgtk_entry_new(void)
Definition: compat.c:142
Compatibility functions for older GTK versions (interface)
#define NSGTK_STOCK_OPEN
Definition: compat.h:65
GtkEntryIconPosition
Definition: compat.h:139
@ GTK_ENTRY_ICON_PRIMARY
Definition: compat.h:140
#define NSGTK_STOCK_REFRESH
Definition: compat.h:60
#define NSGTK_STOCK_SAVE
Definition: compat.h:61
#define NSGTK_STOCK_INFO
Definition: compat.h:59
@ GTK_ALIGN_CENTER
Definition: compat.h:75
#define NSGTK_STOCK_CANCEL
Definition: compat.h:55
#define NSGTK_STOCK_STOP
Definition: compat.h:63
gboolean nsgtk_completion_update(GtkEntry *entry)
update completion list store.
Definition: completion.c:134
nserror nsgtk_completion_connect_signals(GtkEntry *entry, struct browser_window *(*get_bw)(void *ctx), void *get_bw_ctx)
connect signals on entry completion
Definition: completion.c:148
Interface to url entry completion.
@ CONTENT_TEXTPLAIN
content is plain text
Definition: content_type.h:61
@ CONTENT_DEBUG_REDRAW
Debug redraw operations.
Definition: content_type.h:38
@ CONTENT_DEBUG_RENDER
Debug the contents rendering.
Definition: content_type.h:32
@ CONTENT_DEBUG_DOM
Debug the contents Document Object.
Definition: content_type.h:35
Useful interned string pointers (interface).
#define FILE_SCHEME_PREFIX_LEN
File url prefix length.
Definition: corestrings.h:33
#define FILE_SCHEME_PREFIX
File url prefix.
Definition: corestrings.h:30
nserror hotlist_add_url(nsurl *url)
Add an entry to the hotlist for given URL.
Definition: hotlist.c:1431
struct print_settings * print_make_settings(print_configuration configuration, const char *filename, const struct gui_layout_table *font_func)
Generates one of the predefined print settings sets.
Definition: print.c:254
bool print_basic_run(hlcache_handle *content, const struct printer *printer, struct print_settings *settings)
This function calls print setup, prints page after page until the whole content is printed calls clea...
Definition: print.c:64
Conception: Generalized output-in-pages.
@ PRINT_DEFAULT
Definition: print.h:45
@ PRINT_OPTIONS
Definition: print.h:45
const struct printer pdf_printer
void browser_window_search_clear(struct browser_window *bw)
Clear up a search.
Definition: search.c:47
Browseing window text search interface.
nserror search_web_omni(const char *term, enum search_web_omni_flags flags, struct nsurl **url_out)
Generate a nsurl from a search term.
Definition: searchweb.c:318
nserror search_web_get_provider_bitmap(struct bitmap **bitmap_out)
obtain the current providers bitmap
Definition: searchweb.c:370
wimp_w parent
Definition: dialog.c:88
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOT_FOUND
Requested item not found.
Definition: errors.h:34
@ NSERROR_BAD_PARAMETER
Bad Parameter.
Definition: errors.h:48
@ NSERROR_BAD_SIZE
Bad size.
Definition: errors.h:60
@ NSERROR_UNKNOWN
Unknown error - DO NOT USE.
Definition: errors.h:31
@ NSERROR_INVALID
Invalid data.
Definition: errors.h:49
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
const struct font_functions haru_nsfont
void haru_nsfont_set_scale(float s)
void nsgtk_download_show(GtkWindow *parent)
Show the download window.
Definition: download.c:1069
nserror nsgtk_global_history_present(void)
make the global history window visible.
Interface to GTK global history manager.
nserror nsgtk_hotlist_present(void)
make the hotlist window visible.
Definition: hotlist.c:383
Interface to GTK bookmarks (hotlist).
nserror nsgtk_local_history_hide(void)
hide the local history window from being visible.
void nsgtk_local_history_set_position(int x, int y)
set the local history window position.
nserror nsgtk_local_history_present(GtkWindow *parent, struct browser_window *bw)
make the local history window visible.
Interface to GTK local history manager.
void gtk_print_signal_end_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data)
Handle the end_print signal from the GtkPrintOperation.
Definition: print.c:757
static struct print_settings * settings
Definition: print.c:50
struct hlcache_handle * content_to_print
Definition: print.c:51
void gtk_print_signal_draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data)
Handle the draw_page signal from the GtkPrintOperation.
Definition: print.c:745
void gtk_print_signal_begin_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data)
Handle the begin_print signal from the GtkPrintOperation.
Definition: print.c:695
GTK printing (interface).
free text page search for gtk interface
GdkPixbuf * nsgdk_pixbuf_get_from_surface(cairo_surface_t *surface, int scwidth, int scheight)
obtain a pixbuf of the specified size from a cairo surface.
Definition: gdk.c:61
GDK support functions for missing interfaces.
void nsgtk_about_dialog_init(GtkWindow *parent)
Definition: about.c:95
nserror nsgtk_cookies_present(const char *search_term)
make the cookie window visible.
Definition: cookies.c:312
Cookies (interface).
nserror nsgtk_warning(const char *warning, const char *detail)
Warn the user of an event.
Definition: gui.c:95
GdkPixbuf * favicon_pixbuf
favicon default pixbuf
Definition: gui.c:83
char * nsgtk_config_home
Directory where all configuration files are held.
Definition: gui.c:80
nserror nsgtk_schedule(int t, void(*callback)(void *p), void *cbctx)
Definition: schedule.c:103
nserror nsgtk_throbber_get_frame(int frame, GdkPixbuf **pixbuf)
get the pixbuf of a given frame of the throbber
Definition: throbber.c:103
nserror nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid)
activate the handler for a toolbar item
Definition: toolbar.c:3740
static gboolean customisation_container_drag_drop_cb(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data)
customisation container handler for drag drop signal
Definition: toolbar.c:744
static GtkToolItem * make_toolbar_item_websearch(bool sensitivity, bool edit)
create web search toolbar item widget
Definition: toolbar.c:380
static GtkTargetEntry target_entry
target entry for drag source
Definition: toolbar.c:613
static gboolean back_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for back tool bar item clicked signal
Definition: toolbar.c:1777
static gboolean openmenu_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for openmenu tool bar item clicked signal
Definition: toolbar.c:3152
static void toolbar_item_size_allocate_cb(GtkWidget *widget, GtkAllocation *alloc, gpointer data)
callback for all toolbar items widget size allocation
Definition: toolbar.c:1728
#define NSGTK_BUTTON_HEIGHT
the 'standard' height of a button that fits as many toolbars as possible into the store
Definition: toolbar.c:99
static nserror nsgtk_toolbar_customisation_save(struct nsgtk_toolbar *tb)
save toolbar settings to file
Definition: toolbar.c:644
static gboolean debugboxtree_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for debug box tree tool bar item clicked signal
Definition: toolbar.c:2836
static gboolean customisation_apply_clicked_cb(GtkWidget *widget, gpointer data)
customisation apply handler for clicked signal
Definition: toolbar.c:1524
static gboolean forward_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for forward tool bar item clicked signal
Definition: toolbar.c:1809
static gboolean debugdomtree_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for debug dom tree tool bar item clicked signal
Definition: toolbar.c:2881
nserror nsgtk_toolbar_restyle(struct nsgtk_toolbar *tb)
Update toolbar style and size based on current settings.
Definition: toolbar.c:3505
static nserror toolbar_connect_signal(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid)
connect signal handlers to a gtk toolbar item
Definition: toolbar.c:3314
static gboolean history_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for history tool bar item clicked signal
Definition: toolbar.c:2955
static nserror set_item_sensitivity(struct nsgtk_toolbar_item *item, bool sensitivity)
set a toolbar items sensitivity
Definition: toolbar.c:1162
nserror nsgtk_toolbar_set_websearch_image(struct nsgtk_toolbar *tb, GdkPixbuf *pixbuf)
set the websearch image
Definition: toolbar.c:3713
static nserror nsgtk_saveas_dialog(struct browser_window *bw, const char *title, GtkWindow *parent, bool folder, gchar **path_out)
run a gtk file chooser as a save dialog to obtain a path
Definition: toolbar.c:1266
static nserror toolbar_customisation_create_toolbox(struct nsgtk_toolbar_customisation *tbc, int width)
creates widgets in customisation toolbox
Definition: toolbar.c:1449
static nserror set_item_action(struct nsgtk_toolbar *tb, int itemid, bool alt)
set an item to its alternative action
Definition: toolbar.c:1186
static gboolean downloads_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for show downloads tool bar item clicked signal
Definition: toolbar.c:2762
static gboolean fullscreen_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for full screen tool bar item clicked signal
Definition: toolbar.c:2707
static void customisation_container_destroy_cb(GtkWidget *widget, gpointer data)
customisation container destroy handler
Definition: toolbar.c:1558
static gboolean savepage_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for full save export tool bar item clicked signal
Definition: toolbar.c:2204
static gboolean savewindowsize_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for show downloads tool bar item clicked signal
Definition: toolbar.c:2779
static nserror toolbar_connect_signals(struct nsgtk_toolbar *tb)
connect all signals to widgets in a toolbar
Definition: toolbar.c:3381
static gboolean stop_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for stop tool bar item clicked signal
Definition: toolbar.c:1840
static GtkToolItem * make_toolbar_item_throbber(bool sensitivity, bool edit)
create throbber toolbar item widget
Definition: toolbar.c:288
static GtkToolItem * make_toolbox_item(nsgtk_toolbar_button itemid, bool bar)
widget factory for creation of toolbar item widgets for the toolbox
Definition: toolbar.c:558
#define NSGTK_WEBSEARCH_WIDTH
the 'normal' width of the websearch bar
Definition: toolbar.c:104
static nserror toolbar_navigate_to_url(struct nsgtk_toolbar *tb, const char *urltxt)
cause the toolbar browsing context to navigate to a new url.
Definition: toolbar.c:1236
static gboolean customisation_reset_clicked_cb(GtkWidget *widget, gpointer data)
customisation reset handler for clicked signal
Definition: toolbar.c:1544
static gboolean copy_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for copy tool bar item clicked signal
Definition: toolbar.c:2491
nserror nsgtk_toolbar_set_url(struct nsgtk_toolbar *tb, nsurl *url)
Update the toolbar url entry.
Definition: toolbar.c:3662
static nserror toolbar_item_connect_signals(struct nsgtk_toolbar *tb, int itemid)
connect signals to a toolbar item in a customisation toolbar
Definition: toolbar.c:721
static gboolean showcookies_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for show cookies tool bar item clicked signal
Definition: toolbar.c:3029
static gboolean cutomize_button_clicked_cb(GtkWidget *widget, gpointer data)
create a toolbar customisation tab
Definition: toolbar.c:1578
static void item_size_allocate_cb(GtkWidget *widget, GdkRectangle *alloc, gpointer user_data)
Definition: toolbar.c:1374
static void container_remove_widget(GtkWidget *widget, gpointer data)
callback function to remove a widget from a container
Definition: toolbar.c:1056
static gboolean globalhistory_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for global history tool bar item clicked signal
Definition: toolbar.c:2969
static gboolean zoomplus_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for zoom plus tool bar item clicked signal
Definition: toolbar.c:2643
static gboolean openlocation_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for open location tool bar item clicked signal
Definition: toolbar.c:3048
static nserror populate_gtk_toolbar_widget(struct nsgtk_toolbar *tb)
populates a toolbar with widgets in correct order
Definition: toolbar.c:1069
static gboolean zoomnormal_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for zoom normal tool bar item clicked signal
Definition: toolbar.c:2686
static gboolean preferences_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for preferences tool bar item clicked signal
Definition: toolbar.c:2615
#define NSGTK_BUTTON_WIDTH
the 'standard' width of a button that makes sufficient of its label visible
Definition: toolbar.c:93
static nsgtk_toolbar_button itemid_from_gtktoolitem(struct nsgtk_toolbar *tb, GtkToolItem *toolitem)
find the toolbar item with a given gtk widget.
Definition: toolbar.c:1143
static gboolean localhistory_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for local history tool bar item clicked signal
Definition: toolbar.c:2927
static gboolean toggledebugging_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for show downloads tool bar item clicked signal
Definition: toolbar.c:2813
static gboolean about_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for contents tool bar item clicked signal
Definition: toolbar.c:3135
static gboolean viewsource_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for view source tool bar item clicked signal
Definition: toolbar.c:2734
static nserror set_throbber_frame(GtkToolItem *toolbar_item, int frame)
set a toolbar item to a throbber frame number
Definition: toolbar.c:3257
nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, struct nsgtk_pi_window *win)
position the page info window appropriately
Definition: toolbar.c:3857
static gboolean zoomminus_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for zoom minus tool bar item clicked signal
Definition: toolbar.c:2664
static nserror toolbar_item_create(nsgtk_toolbar_button id, struct nsgtk_toolbar_item *item_out)
create a toolbar item
Definition: toolbar.c:3210
static GtkToolItem * make_toolbar_item_url_bar(bool sensitivity, bool edit)
create url bar toolbar item widget
Definition: toolbar.c:334
static gboolean selectall_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for select all tool bar item clicked signal
Definition: toolbar.c:2584
static gboolean guide_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for contents tool bar item clicked signal
Definition: toolbar.c:3092
static nserror customisation_toolbar_update(struct nsgtk_toolbar_customisation *tbc)
update toolbar in customisation to user settings
Definition: toolbar.c:1487
static gboolean customisation_toolbar_drag_drop_cb(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data)
customisation toolbar handler for drag drop signal
Definition: toolbar.c:811
static gboolean info_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for contents tool bar item clicked signal
Definition: toolbar.c:3114
static gboolean toolbar_popup_context_menu_cb(GtkToolbar *toolbar, gint x, gint y, gint button, gpointer data)
signal handler for toolbar context menu
Definition: toolbar.c:3410
nserror nsgtk_toolbar_position_local_history(struct nsgtk_toolbar *tb)
position the local history window appropriately
Definition: toolbar.c:3874
static gboolean customisation_toolbar_drag_motion_cb(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data)
customisation toolbar handler for drag motion signal
Definition: toolbar.c:910
static gboolean newtab_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for new tab tool bar item clicked signal
Definition: toolbar.c:2100
nserror nsgtk_toolbar_create(GtkBuilder *builder, struct browser_window *(*get_bw)(void *ctx), void *get_ctx, bool want_location_focus, struct nsgtk_toolbar **tb_out)
create a control toolbar
Definition: toolbar.c:3447
static gboolean plaintext_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for plain text export tool bar item clicked signal
Definition: toolbar.c:2308
static void toolbar_destroy_cb(GtkWidget *widget, gpointer data)
toolbar delete signal handler
Definition: toolbar.c:3433
static char * remove_underscores(const char *s, bool replacespace)
returns a string without its underscores
Definition: toolbar.c:261
nsgtk_toolbar_location_focus_state
Location focus state machine.
Definition: toolbar.c:160
@ LFS_IDLE
Nothing to do.
Definition: toolbar.c:161
@ LFS_LAST
Last chance for a focus update.
Definition: toolbar.c:164
@ LFS_WANT
Want focus, will apply.
Definition: toolbar.c:162
@ LFS_THROB
Want focus, we have started throbbing.
Definition: toolbar.c:163
static gboolean websearch_entry_activate_cb(GtkWidget *widget, gpointer data)
handler for web search tool bar entry item activate signal
Definition: toolbar.c:2018
static GtkToolItem * make_toolbar_item_button(const char *labelmsg, const char *iconname, bool sensitivity, bool edit)
create generic button toolbar item widget
Definition: toolbar.c:465
static void customisation_toolbar_drag_leave_cb(GtkWidget *widget, GdkDragContext *gdc, guint time, gpointer data)
customisation toolbar handler for drag leave signal
Definition: toolbar.c:936
static gboolean customisation_container_drag_motion_cb(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data)
customisation container handler for drag motion signal
Definition: toolbar.c:795
nserror nsgtk_toolbar_page_info_change(struct nsgtk_toolbar *tb)
Page info has changed state.
Definition: toolbar.c:3607
static GtkToolItem * make_toolbar_item_history(bool sensitivity, bool edit)
create local history toolbar item widget
Definition: toolbar.c:437
static gboolean showbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for show bookmark tool bar item clicked signal
Definition: toolbar.c:3010
static nserror apply_user_button_customisation(struct nsgtk_toolbar *tb)
Apply the user toolbar button settings from configuration.
Definition: toolbar.c:998
static nserror add_toolbox_row(struct nsgtk_toolbar_customisation *tbc, int startitem, int enditem)
add a row to a toolbar customisation toolbox
Definition: toolbar.c:1397
nserror nsgtk_toolbar_show(struct nsgtk_toolbar *tb, bool show)
set the toolbar to be shown or hidden
Definition: toolbar.c:3771
static gboolean closewindow_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for close window tool bar item clicked signal
Definition: toolbar.c:2187
static void url_entry_icon_release_cb(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer data)
callback for url entry widget icon button release
Definition: toolbar.c:1992
static nserror nsgtk_toolbar_get_icon_window_position(struct nsgtk_toolbar *tb, int item_idx, int *out_x, int *out_y)
Find the correct location for popping up a window for the chosen item.
Definition: toolbar.c:3819
static gboolean addbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for add bookmark tool bar item clicked signal
Definition: toolbar.c:2989
static nserror customisation_toolbar_populate(struct nsgtk_toolbar *tb)
populates the customization toolbar with widgets in correct order
Definition: toolbar.c:1106
static gboolean reloadstop_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for reload/stop tool bar item clicked signal
Definition: toolbar.c:1882
static gboolean url_entry_changed_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
callback for url entry widget changing
Definition: toolbar.c:1975
static gboolean pdf_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for pdf export tool bar item clicked signal
Definition: toolbar.c:2256
nserror nsgtk_toolbar_update(struct nsgtk_toolbar *tb)
Update the toolbar items being shown based on current settings.
Definition: toolbar.c:3783
static gboolean openfile_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for open file tool bar item clicked signal
Definition: toolbar.c:2121
#define THROBBER_FRAME_TIME
time (in ms) between throbber animation frame updates
Definition: toolbar.c:83
#define NSGTK_MIN_STORE_COLUMNS
the minimum number of columns in the tool store
Definition: toolbar.c:88
static gboolean customisation_toolbar_drag_data_received_cb(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, GtkSelectionData *selection, guint info, guint time, gpointer data)
customisation toolbar handler for drag data received signal
Definition: toolbar.c:891
nserror nsgtk_toolbar_throbber(struct nsgtk_toolbar *tb, bool active)
Start or stop a throbber in a toolbar.
Definition: toolbar.c:3550
static gboolean websearch_entry_button_press_cb(GtkWidget *widget, GdkEventFocus *f, gpointer data)
handler for web search tool bar item button press signal
Definition: toolbar.c:2059
static gboolean print_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for print tool bar item clicked signal
Definition: toolbar.c:2345
static gboolean contents_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for contents tool bar item clicked signal
Definition: toolbar.c:3071
static nserror nsgtk_browser_window_create(struct browser_window *bw, bool intab)
create a new browser window
Definition: toolbar.c:956
static gboolean paste_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for paste tool bar item clicked signal
Definition: toolbar.c:2522
static GtkToolItem * make_toolbar_item(nsgtk_toolbar_button itemid, bool sensitivity)
widget factory for creation of toolbar item widgets
Definition: toolbar.c:501
static gboolean url_entry_activate_cb(GtkWidget *widget, gpointer data)
callback for url entry widget activation
Definition: toolbar.c:1940
static nsgtk_toolbar_button itemid_from_location(struct nsgtk_toolbar *tb, int location)
find the toolbar item with a given location.
Definition: toolbar.c:628
static gboolean home_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for home tool bar item clicked signal
Definition: toolbar.c:1910
#define INACTIVE_LOCATION
button location indicating button is not to be shown
Definition: toolbar.c:78
static gboolean reload_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for reload tool bar item clicked signal
Definition: toolbar.c:1858
static gboolean newwindow_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for new window tool bar item clicked signal
Definition: toolbar.c:2078
static nserror toolbar_customisation_connect_signals(struct nsgtk_toolbar *tb)
connect all signals to widgets in a customisation
Definition: toolbar.c:1333
static gboolean quit_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for quit tool bar item clicked signal
Definition: toolbar.c:2445
static void next_throbber_frame(void *p)
Make the throbber run.
Definition: toolbar.c:3288
static gboolean cut_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for cut tool bar item clicked signal
Definition: toolbar.c:2460
static gboolean delete_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for delete tool bar item clicked signal
Definition: toolbar.c:2553
struct nsgtk_scaffolding * nsgtk_get_scaffold(struct gui_window *g)
get containing nsgtk scaffolding handle from gui window handle
Definition: window.c:1612
nserror nsgtk_window_update_all(void)
Every window will have its tab, toolbar and drawing area updated.
Definition: window.c:1657
nserror nsgtk_window_toolbar_update(void)
every window will have its toolbar updated to reflect user settings
Definition: window.c:1684
Public content interface.
content_type content_get_type(struct hlcache_handle *h)
Retrieve computed type of content.
Definition: content.c:1061
Interface to key press operations.
@ NS_KEY_SELECT_ALL
Definition: keypress.h:32
@ NS_KEY_PASTE
Definition: keypress.h:43
@ NS_KEY_COPY_SELECTION
Definition: keypress.h:33
@ NS_KEY_CUT_SELECTION
Definition: keypress.h:44
@ NS_KEY_CLEAR_SELECTION
Definition: keypress.h:45
bool browser_window_key_press(struct browser_window *bw, uint32_t key)
Handle key presses in a browser window.
Definition: textinput.c:107
struct gui_layout_table * nsgtk_layout_table
Definition: layout_pango.c:309
Interface to GTK layout handling using pango.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
const char * messages_get_errorcode(nserror code)
lookup of a message by errorcode from the standard Messages hash.
Definition: messages.c:248
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
NetSurf URL handling (interface).
nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l)
Get a UTF-8 string (for human readable IDNs) from a NetSurf URL object.
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
nserror nsurl_nice(const nsurl *url, char **result, bool remove_extensions)
Attempt to find a nice filename for a URL.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
void nsgtk_page_info_set_position(struct nsgtk_pi_window *win, int x, int y)
Position the given page information window at the given coordinates.
Definition: page_info.c:253
nserror nsgtk_page_info(struct browser_window *bw)
Page information window.
Definition: page_info.c:163
GtkWidget * nsgtk_preferences(struct browser_window *bw, GtkWindow *parent)
Initialise prefernces window.
Definition: preferences.c:951
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.
int width
Definition: gui.c:159
nserror save_complete(hlcache_handle *c, const char *path, save_complete_set_type_cb set_type)
Save an HTML page with all dependencies.
Save HTML document with dependencies (interface).
void save_as_text(struct hlcache_handle *c, char *path)
Extract the text from an HTML content and save it as a text file.
Definition: save_text.c:57
Text export of HTML (interface).
nserror nsgtk_scaffolding_toolbar_context_menu(struct nsgtk_scaffolding *gs)
open the toolbar context menu
Definition: scaffolding.c:1407
nserror nsgtk_scaffolding_burger_menu(struct nsgtk_scaffolding *gs)
open the burger menu
Definition: scaffolding.c:1419
nserror nsgtk_scaffolding_destroy_all(void)
causes all scaffolding windows to be destroyed.
Definition: scaffolding.c:1288
core web search facilities interface.
@ SEARCH_WEB_OMNI_NONE
no changes to default operation
Definition: searchweb.h:50
@ SEARCH_WEB_OMNI_SEARCHONLY
The search does not attempt to interpret the url as a url before using it as a search term.
Definition: searchweb.h:55
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
cairo_surface_t * surface
Definition: bitmap.h:27
Browser window data.
int x
Window dimensions.
struct browser_window * bw
Column record for a table.
Definition: box_normalise.c:59
first entry in window list
Definition: gui.c:296
GTK certificate viewing window context.
Definition: page_info.c:47
Core scaffolding structure.
Definition: scaffolding.c:64
toolbar cusomisation context
Definition: toolbar.c:215
GtkToolItem * items[PLACEHOLDER_BUTTON]
widget handles for items in the customisation toolbox area
Definition: toolbar.c:235
bool dragfrom
true if item being dragged onto toolbar, false if from toolbar
Definition: toolbar.c:244
struct nsgtk_toolbar toolbar
first entry is a toolbar widget so a customisation widget can be cast to toolbar and back.
Definition: toolbar.c:220
int dragitem
which item is being dragged
Definition: toolbar.c:240
GtkWidget * container
The top level container (tabBox)
Definition: toolbar.c:225
GtkBox * toolbox
The vertical box into which the available tools are shown.
Definition: toolbar.c:230
toolbar item context
Definition: toolbar.c:109
gboolean(* clicked)(GtkWidget *widget, gpointer data)
button clicked on toolbar handler
Definition: toolbar.c:134
int location
location index in toolbar
Definition: toolbar.c:119
void * dataplus
handler when dragging from customisation toolbox to toolbar
Definition: toolbar.c:139
const char * name
textural name used in serialising items
Definition: toolbar.c:129
GtkToolItem * button
GTK widget in the toolbar.
Definition: toolbar.c:114
void * dataminus
handler when dragging from toolbar to customisation toolbox
Definition: toolbar.c:144
bool sensitivity
if the item is currently sensitive in the toolbar
Definition: toolbar.c:124
control toolbar context
Definition: toolbar.c:170
int toolbarmem
Definition: toolbar.c:176
nsgtk_toolbar_location_focus_state loc_focus
Location focus state machine, current state.
Definition: toolbar.c:208
int throb_frame
Current frame of throbber animation.
Definition: toolbar.c:188
int toolbarbase
Definition: toolbar.c:177
int historybase
Definition: toolbar.c:178
GtkToolbar * widget
gtk toolbar widget
Definition: toolbar.c:172
GtkWidget * webSearchEntry
Web search widget.
Definition: toolbar.c:193
struct nsgtk_toolbar_item items[PLACEHOLDER_BUTTON]
Toolbar item contexts.
Definition: toolbar.c:183
struct browser_window *(* get_bw)(void *ctx)
callback to obtain a browser window for navigation
Definition: toolbar.c:198
void * get_ctx
context passed to get_bw function
Definition: toolbar.c:203
Settings for a print - filled in by print_make_settings or 'manually' by the caller.
Definition: print.h:50
nserror nsgtk_tab_add_page(GtkNotebook *notebook, GtkWidget *tab_contents, bool background, const char *title, GdkPixbuf *icon_pixbuf)
Add new page to a notebook.
Definition: tabs.c:418
nsgtk_toolbar_button
Definition: toolbar_items.h:22
@ THROBBER_ITEM
Definition: toolbar_items.h:33
@ WEBSEARCH_ITEM
Definition: toolbar_items.h:28
@ BACK_BUTTON
Definition: toolbar_items.h:23
@ HISTORY_BUTTON
Definition: toolbar_items.h:24
@ OPENMENU_BUTTON
Definition: toolbar_items.h:29
@ URL_BAR_ITEM
Definition: toolbar_items.h:27
@ RELOAD_BUTTON
Definition: toolbar_items.h:31
@ FORWARD_BUTTON
Definition: toolbar_items.h:25
@ PLACEHOLDER_BUTTON
Definition: toolbar_items.h:77
@ STOP_BUTTON
Definition: toolbar_items.h:30
@ RELOADSTOP_BUTTON
Definition: toolbar_items.h:26
nserror netsurf_mkpath(char **str, size_t *size, size_t nelm,...)
Generate a path from one or more component elemnts.
Definition: file.c:288
Default operations table for files.
nserror nsoption_write(const char *path, struct nsoption_s *opts, struct nsoption_s *defs)
Write options that have changed from the defaults to a file.
Definition: nsoption.c:763
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:297
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279
#define nsoption_set_int(OPTION, VALUE)
set an integer option in the default table
Definition: nsoption.h:314
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:338
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
nserror nsgtk_viewfile(const char *title, const char *leafname, const char *filename)
Display file to a user.
Definition: viewdata.c:966
nserror nsgtk_viewsource(GtkWindow *parent, struct browser_window *bw)
Definition: viewsource.c:33
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821
static nserror bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:857