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
2857 } else {
2858 bw = tb->get_bw(tb->get_ctx);
2859
2861
2862 fclose(f);
2863
2864 nsgtk_viewfile("Box Tree Debug", "boxtree", fname);
2865 }
2866 g_free(fname);
2867
2868 return TRUE;
2869}
2870
2871
2872/**
2873 * handler for debug dom tree tool bar item clicked signal
2874 *
2875 * \param widget The widget the signal is being delivered to.
2876 * \param data The toolbar context passed when the signal was connected
2877 * \return TRUE
2878 */
2879static gboolean
2880debugdomtree_button_clicked_cb(GtkWidget *widget, gpointer data)
2881{
2882 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2883 struct browser_window *bw;
2884 gchar *fname;
2885 gint handle;
2886 FILE *f;
2887
2888 handle = g_file_open_tmp("nsgtkdomtreeXXXXXX", &fname, NULL);
2889 if ((handle == -1) || (fname == NULL)) {
2890 return TRUE;
2891 }
2892 close(handle); /* in case it was binary mode */
2893
2894 /* save data to temporary file */
2895 f = fopen(fname, "w");
2896 if (f == NULL) {
2897 nsgtk_warning("Error saving box tree dump.",
2898 "Unable to open file for writing.");
2899 unlink(fname);
2900
2901 } else {
2902 bw = tb->get_bw(tb->get_ctx);
2903
2905
2906 fclose(f);
2907
2908 nsgtk_viewfile("DOM Tree Debug", "domtree", fname);
2909 }
2910 g_free(fname);
2911
2912 return TRUE;
2913
2914}
2915
2916
2917/**
2918 * handler for local history tool bar item clicked signal
2919 *
2920 * \param widget The widget the signal is being delivered to.
2921 * \param data The toolbar context passed when the signal was connected
2922 * \return TRUE
2923 */
2924static gboolean
2925localhistory_button_clicked_cb(GtkWidget *widget, gpointer data)
2926{
2927 nserror res;
2928 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2929 struct browser_window *bw;
2930 GtkWidget *toplevel;
2931
2932 toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
2933 if (toplevel != NULL) {
2934 bw = tb->get_bw(tb->get_ctx);
2935
2936 res = nsgtk_local_history_present(GTK_WINDOW(toplevel), bw);
2937 if (res != NSERROR_OK) {
2938 NSLOG(netsurf, INFO,
2939 "Unable to present local history window.");
2940 }
2941 }
2942 return TRUE;
2943}
2944
2945/**
2946 * handler for history tool bar item clicked signal
2947 *
2948 * \param widget The widget the signal is being delivered to.
2949 * \param data The toolbar context passed when the signal was connected
2950 * \return TRUE
2951 */
2952static gboolean
2953history_button_clicked_cb(GtkWidget *widget, gpointer data)
2954{
2955 return localhistory_button_clicked_cb(widget, data);
2956}
2957
2958
2959/**
2960 * handler for global history tool bar item clicked signal
2961 *
2962 * \param widget The widget the signal is being delivered to.
2963 * \param data The toolbar context passed when the signal was connected
2964 * \return TRUE
2965 */
2966static gboolean
2967globalhistory_button_clicked_cb(GtkWidget *widget, gpointer data)
2968{
2969 nserror res;
2971 if (res != NSERROR_OK) {
2972 NSLOG(netsurf, INFO,
2973 "Unable to initialise global history window.");
2974 }
2975 return TRUE;
2976}
2977
2978
2979/**
2980 * handler for add bookmark tool bar item clicked signal
2981 *
2982 * \param widget The widget the signal is being delivered to.
2983 * \param data The toolbar context passed when the signal was connected
2984 * \return TRUE
2985 */
2986static gboolean
2987addbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
2988{
2989 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
2990 struct browser_window *bw;
2991
2992 bw = tb->get_bw(tb->get_ctx);
2995 }
2996 return TRUE;
2997}
2998
2999
3000/**
3001 * handler for show bookmark tool bar item clicked signal
3002 *
3003 * \param widget The widget the signal is being delivered to.
3004 * \param data The toolbar context passed when the signal was connected
3005 * \return TRUE
3006 */
3007static gboolean
3008showbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
3009{
3010 nserror res;
3011 res = nsgtk_hotlist_present();
3012 if (res != NSERROR_OK) {
3013 NSLOG(netsurf, INFO, "Unable to initialise bookmark window.");
3014 }
3015 return TRUE;
3016}
3017
3018
3019/**
3020 * handler for show cookies tool bar item clicked signal
3021 *
3022 * \param widget The widget the signal is being delivered to.
3023 * \param data The toolbar context passed when the signal was connected
3024 * \return TRUE
3025 */
3026static gboolean
3027showcookies_button_clicked_cb(GtkWidget *widget, gpointer data)
3028{
3029 nserror res;
3030 res = nsgtk_cookies_present(NULL);
3031 if (res != NSERROR_OK) {
3032 NSLOG(netsurf, INFO, "Unable to initialise cookies window.");
3033 }
3034 return TRUE;
3035}
3036
3037
3038/**
3039 * handler for open location tool bar item clicked signal
3040 *
3041 * \param widget The widget the signal is being delivered to.
3042 * \param data The toolbar context passed when the signal was connected
3043 * \return TRUE
3044 */
3045static gboolean
3046openlocation_button_clicked_cb(GtkWidget *widget, gpointer data)
3047{
3048 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3049 GtkToolItem *urltitem;
3050
3051 urltitem = tb->items[URL_BAR_ITEM].button;
3052 if (urltitem != NULL) {
3053 GtkEntry *entry;
3054 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(urltitem)));
3055 gtk_widget_grab_focus(GTK_WIDGET(entry));
3056 }
3057 return TRUE;
3058}
3059
3060
3061/**
3062 * handler for contents tool bar item clicked signal
3063 *
3064 * \param widget The widget the signal is being delivered to.
3065 * \param data The toolbar context passed when the signal was connected
3066 * \return TRUE
3067 */
3068static gboolean
3069contents_button_clicked_cb(GtkWidget *widget, gpointer data)
3070{
3071 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3072 nserror res;
3073
3074 res = toolbar_navigate_to_url(tb, "https://www.netsurf-browser.org/documentation/");
3075 if (res != NSERROR_OK) {
3077 }
3078
3079 return TRUE;
3080}
3081
3082/**
3083 * handler for contents tool bar item clicked signal
3084 *
3085 * \param widget The widget the signal is being delivered to.
3086 * \param data The toolbar context passed when the signal was connected
3087 * \return TRUE
3088 */
3089static gboolean
3090guide_button_clicked_cb(GtkWidget *widget, gpointer data)
3091{
3092 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3093 nserror res;
3094
3095 res = toolbar_navigate_to_url(tb, "https://www.netsurf-browser.org/documentation/guide");
3096 if (res != NSERROR_OK) {
3098 }
3099
3100 return TRUE;
3101}
3102
3103
3104/**
3105 * handler for contents tool bar item clicked signal
3106 *
3107 * \param widget The widget the signal is being delivered to.
3108 * \param data The toolbar context passed when the signal was connected
3109 * \return TRUE
3110 */
3111static gboolean
3112info_button_clicked_cb(GtkWidget *widget, gpointer data)
3113{
3114 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3115 nserror res;
3116
3117 res = toolbar_navigate_to_url(tb, "https://www.netsurf-browser.org/documentation/info");
3118 if (res != NSERROR_OK) {
3120 }
3121
3122 return TRUE;
3123}
3124
3125
3126/**
3127 * handler for contents tool bar item clicked signal
3128 *
3129 * \param widget The widget the signal is being delivered to.
3130 * \param data The toolbar context passed when the signal was connected
3131 * \return TRUE
3132 */
3133static gboolean about_button_clicked_cb(GtkWidget *widget, gpointer data)
3134{
3135 GtkWindow *parent; /* gtk window widget is in */
3136
3137 parent = GTK_WINDOW(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW));
3138
3140 return TRUE;
3141}
3142
3143/**
3144 * handler for openmenu tool bar item clicked signal
3145 *
3146 * \param widget The widget the signal is being delivered to.
3147 * \param data The toolbar context passed when the signal was connected
3148 * \return TRUE to indicate signal handled.
3149 */
3150static gboolean openmenu_button_clicked_cb(GtkWidget *widget, gpointer data)
3151{
3152 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3153 struct gui_window *gw;
3154 struct nsgtk_scaffolding *gs;
3155
3156 gw = tb->get_ctx; /** \todo stop assuming the context is a gui window */
3157
3158 gs = nsgtk_get_scaffold(gw);
3159
3161
3162 return TRUE;
3163}
3164
3165
3166/* define data plus and data minus handlers */
3167#define TOOLBAR_ITEM(identifier, name, snstvty, clicked, activate, label, iconame) \
3168static gboolean \
3169nsgtk_toolbar_##name##_data_plus(GtkWidget *widget, \
3170 GdkDragContext *cont, \
3171 GtkSelectionData *selection, \
3172 guint info, \
3173 guint time, \
3174 gpointer data) \
3175{ \
3176 struct nsgtk_toolbar_customisation *tbc; \
3177 tbc = (struct nsgtk_toolbar_customisation *)data; \
3178 tbc->dragitem = identifier; \
3179 tbc->dragfrom = true; \
3180 return TRUE; \
3181} \
3182static gboolean \
3183nsgtk_toolbar_##name##_data_minus(GtkWidget *widget, \
3184 GdkDragContext *cont, \
3185 GtkSelectionData *selection, \
3186 guint info, \
3187 guint time, \
3188 gpointer data) \
3189{ \
3190 struct nsgtk_toolbar_customisation *tbc; \
3191 tbc = (struct nsgtk_toolbar_customisation *)data; \
3192 tbc->dragitem = identifier; \
3193 tbc->dragfrom = false; \
3194 return TRUE; \
3195}
3196
3197#include "gtk/toolbar_items.h"
3198
3199#undef TOOLBAR_ITEM
3200
3201
3202/**
3203 * create a toolbar item
3204 *
3205 * create a toolbar item and set up its default handlers
3206 */
3207static nserror
3209{
3211
3212 /* set item defaults from macro */
3213 switch (id) {
3214#define TOOLBAR_ITEM_t(name) \
3215 item->clicked = name##_button_clicked_cb;
3216#define TOOLBAR_ITEM_b(name) \
3217 item->clicked = name##_button_clicked_cb;
3218#define TOOLBAR_ITEM_y(name) \
3219 item->clicked = name##_button_clicked_cb;
3220#define TOOLBAR_ITEM_n(name) \
3221 item->clicked = NULL;
3222#define TOOLBAR_ITEM(identifier, iname, snstvty, clicked, activate, label, iconame) \
3223 case identifier: \
3224 item->name = #iname; \
3225 item->sensitivity = snstvty; \
3226 item->dataplus = nsgtk_toolbar_##iname##_data_plus; \
3227 item->dataminus = nsgtk_toolbar_##iname##_data_minus; \
3228 TOOLBAR_ITEM_ ## clicked(iname) \
3229 break;
3230
3231#include "gtk/toolbar_items.h"
3232
3233#undef TOOLBAR_ITEM_t
3234#undef TOOLBAR_ITEM_y
3235#undef TOOLBAR_ITEM_n
3236#undef TOOLBAR_ITEM
3237
3238 case PLACEHOLDER_BUTTON:
3239 return NSERROR_INVALID;
3240 }
3241
3242 return NSERROR_OK;
3243}
3244
3245
3246/**
3247 * set a toolbar item to a throbber frame number
3248 *
3249 * \param toolbar_item The toolbar item to update
3250 * \param frame The animation frame number to update to
3251 * \return NSERROR_OK on success,
3252 * NSERROR_INVALID if the toolbar item does not contain an image,
3253 * NSERROR_BAD_SIZE if the frame is out of range.
3254 */
3255static nserror set_throbber_frame(GtkToolItem *toolbar_item, int frame)
3256{
3257 nserror res;
3258 GdkPixbuf *pixbuf;
3259 GtkImage *throbber;
3260
3261 if (toolbar_item == NULL) {
3262 /* no toolbar item */
3263 return NSERROR_INVALID;
3264 }
3265
3266 res = nsgtk_throbber_get_frame(frame, &pixbuf);
3267 if (res != NSERROR_OK) {
3268 return res;
3269 }
3270
3271 throbber = GTK_IMAGE(gtk_bin_get_child(GTK_BIN(toolbar_item)));
3272
3273 gtk_image_set_from_pixbuf(throbber, pixbuf);
3274
3275 return NSERROR_OK;
3276}
3277
3278
3279/**
3280 * Make the throbber run.
3281 *
3282 * scheduled callback to update the throbber
3283 *
3284 * \param p The context passed when scheduled.
3285 */
3286static void next_throbber_frame(void *p)
3287{
3288 struct nsgtk_toolbar *tb = p;
3289 nserror res;
3290
3291 tb->throb_frame++; /* advance to next frame */
3292
3294 tb->throb_frame);
3295 if (res == NSERROR_BAD_SIZE) {
3296 tb->throb_frame = 1;
3298 tb->throb_frame);
3299 }
3300
3301 /* only schedule next frame if there are no errors */
3302 if (res == NSERROR_OK) {
3304 }
3305}
3306
3307
3308/**
3309 * connect signal handlers to a gtk toolbar item
3310 */
3311static nserror
3313{
3314 struct nsgtk_toolbar_item *item;
3315 GtkEntry *entry;
3316
3317 item = &tb->items[itemid];
3318
3319 if (item->button != NULL) {
3320 g_signal_connect(item->button,
3321 "size-allocate",
3323 tb);
3324 }
3325
3326 switch (itemid) {
3327 case URL_BAR_ITEM:
3328 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(item->button)));
3329
3330 g_signal_connect(GTK_WIDGET(entry),
3331 "activate",
3332 G_CALLBACK(url_entry_activate_cb),
3333 tb);
3334 g_signal_connect(GTK_WIDGET(entry),
3335 "changed",
3336 G_CALLBACK(url_entry_changed_cb),
3337 tb);
3338 g_signal_connect(GTK_WIDGET(entry),
3339 "icon-release",
3340 G_CALLBACK(url_entry_icon_release_cb),
3341 tb);
3342
3344 tb->get_bw,
3345 tb->get_ctx);
3346 break;
3347
3348
3349 case WEBSEARCH_ITEM:
3350 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(item->button)));
3351
3352 g_signal_connect(GTK_WIDGET(entry),
3353 "activate",
3354 G_CALLBACK(websearch_entry_activate_cb),
3355 tb);
3356 g_signal_connect(GTK_WIDGET(entry),
3357 "button-press-event",
3359 tb);
3360 break;
3361
3362 default:
3363 if ((item->clicked != NULL) && (item->button != NULL)) {
3364 g_signal_connect(item->button,
3365 "clicked",
3366 G_CALLBACK(item->clicked),
3367 tb);
3368 }
3369 break;
3370
3371 }
3372
3373 return NSERROR_OK;
3374}
3375
3376/**
3377 * connect all signals to widgets in a toolbar
3378 */
3380{
3381 int location; /* location index */
3382 nsgtk_toolbar_button itemid; /* item id */
3383
3385 itemid = itemid_from_location(tb, location);
3386 if (itemid == PLACEHOLDER_BUTTON) {
3387 /* no more filled locations */
3388 break;
3389 }
3390 toolbar_connect_signal(tb, itemid);
3391 }
3392
3393 return NSERROR_OK;
3394}
3395
3396
3397/**
3398 * signal handler for toolbar context menu
3399 *
3400 * \param toolbar The toolbar event is being delivered to
3401 * \param x The x coordinate where the click happened
3402 * \param y The x coordinate where the click happened
3403 * \param button the buttons being pressed
3404 * \param data The context pointer passed when the connection was made.
3405 * \return TRUE to indicate signal handled.
3406 */
3407static gboolean
3409 gint x,
3410 gint y,
3411 gint button,
3412 gpointer data)
3413{
3414 struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
3415 struct gui_window *gw;
3416 struct nsgtk_scaffolding *gs;
3417
3418 gw = tb->get_ctx; /** \todo stop assuming the context is a gui window */
3419
3420 gs = nsgtk_get_scaffold(gw);
3421
3423
3424 return TRUE;
3425}
3426
3427
3428/**
3429 * toolbar delete signal handler
3430 */
3431static void toolbar_destroy_cb(GtkWidget *widget, gpointer data)
3432{
3433 struct nsgtk_toolbar *tb;
3434 tb = (struct nsgtk_toolbar *)data;
3435
3436 /* ensure any throbber scheduled is stopped */
3438
3439 free(tb);
3440}
3441
3442
3443/* exported interface documented in toolbar.h */
3444nserror
3445nsgtk_toolbar_create(GtkBuilder *builder,
3446 struct browser_window *(*get_bw)(void *ctx),
3447 void *get_ctx,
3448 bool want_location_focus,
3449 struct nsgtk_toolbar **tb_out)
3450{
3451 nserror res;
3452 struct nsgtk_toolbar *tb;
3453 int bidx; /* button index */
3454
3455 tb = calloc(1, sizeof(struct nsgtk_toolbar));
3456 if (tb == NULL) {
3457 return NSERROR_NOMEM;
3458 }
3459
3460 tb->get_bw = get_bw;
3461 tb->get_ctx = get_ctx;
3462 /* set the throbber start frame. */
3463 tb->throb_frame = 0;
3464 if (want_location_focus) {
3465 tb->loc_focus = LFS_WANT;
3466 } else {
3467 tb->loc_focus = LFS_IDLE;
3468 }
3469
3470 tb->widget = GTK_TOOLBAR(gtk_builder_get_object(builder, "toolbar"));
3471 gtk_toolbar_set_show_arrow(tb->widget, TRUE);
3472
3473 g_signal_connect(tb->widget,
3474 "popup-context-menu",
3476 tb);
3477
3478 /* close and cleanup on delete signal */
3479 g_signal_connect(tb->widget,
3480 "destroy",
3481 G_CALLBACK(toolbar_destroy_cb),
3482 tb);
3483
3484 /* allocate button contexts */
3485 for (bidx = BACK_BUTTON; bidx < PLACEHOLDER_BUTTON; bidx++) {
3486 res = toolbar_item_create(bidx, &tb->items[bidx]);
3487 if (res != NSERROR_OK) {
3488 return res;
3489 }
3490 }
3491
3492 res = nsgtk_toolbar_update(tb);
3493 if (res != NSERROR_OK) {
3494 return res;
3495 }
3496
3497 *tb_out = tb;
3498 return NSERROR_OK;
3499}
3500
3501
3502/* exported interface documented in toolbar.h */
3504{
3505 /*
3506 * reset toolbar size allocation so icon size change affects
3507 * allocated widths.
3508 */
3509 tb->offset = 0;
3510
3511 switch (nsoption_int(button_type)) {
3512
3513 case 1: /* Small icons */
3514 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3515 GTK_TOOLBAR_ICONS);
3516 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb->widget),
3517 GTK_ICON_SIZE_SMALL_TOOLBAR);
3518 break;
3519
3520 case 2: /* Large icons */
3521 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3522 GTK_TOOLBAR_ICONS);
3523 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb->widget),
3524 GTK_ICON_SIZE_LARGE_TOOLBAR);
3525 break;
3526
3527 case 3: /* Large icons with text */
3528 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3529 GTK_TOOLBAR_BOTH);
3530 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb->widget),
3531 GTK_ICON_SIZE_LARGE_TOOLBAR);
3532 break;
3533
3534 case 4: /* Text icons only */
3535 gtk_toolbar_set_style(GTK_TOOLBAR(tb->widget),
3536 GTK_TOOLBAR_TEXT);
3537 break;
3538
3539 default:
3540 break;
3541 }
3542
3543 return NSERROR_OK;
3544}
3545
3546
3547/* exported interface documented in toolbar.h */
3549{
3550 nserror res;
3551 struct browser_window *bw;
3552
3553 /* Manage the location focus state */
3554 switch (tb->loc_focus) {
3555 case LFS_IDLE:
3556 break;
3557 case LFS_WANT:
3558 if (active) {
3559 tb->loc_focus = LFS_THROB;
3560 }
3561 break;
3562 case LFS_THROB:
3563 if (!active) {
3564 tb->loc_focus = LFS_LAST;
3565 }
3566 break;
3567 case LFS_LAST:
3568 break;
3569 }
3570
3571 /* when activating the throbber simply schedule the next frame update */
3572 if (active) {
3574
3578
3579 return NSERROR_OK;
3580 }
3581
3582 /* stopping the throbber */
3584 tb->throb_frame = 0;
3586 tb->throb_frame);
3587
3588 bw = tb->get_bw(tb->get_ctx);
3589
3590 /* adjust sensitivity of other items */
3599
3600 return res;
3601}
3602
3603
3604/* exported interface documented in toolbar.h */
3606{
3607 GtkEntry *url_entry;
3609 struct browser_window *bw;
3610 const char *icon_name;
3611
3612 if (tb->items[URL_BAR_ITEM].button == NULL) {
3613 /* no toolbar item */
3614 return NSERROR_INVALID;
3615 }
3616 url_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(tb->items[URL_BAR_ITEM].button)));
3617
3618 bw = tb->get_bw(tb->get_ctx);
3619
3621
3622 switch (pistate) {
3624 icon_name = "page-info-internal";
3625 break;
3626
3627 case PAGE_STATE_LOCAL:
3628 icon_name = "page-info-local";
3629 break;
3630
3632 icon_name = "page-info-insecure";
3633 break;
3634
3636 icon_name = "page-info-warning";
3637 break;
3638
3640 icon_name = "page-info-warning";
3641 break;
3642
3643 case PAGE_STATE_SECURE:
3644 icon_name = "page-info-secure";
3645 break;
3646
3647 default:
3648 icon_name = "page-info-internal";
3649 break;
3650 }
3651
3652 nsgtk_entry_set_icon_from_icon_name(GTK_WIDGET(url_entry),
3654 icon_name);
3655 return NSERROR_OK;
3656}
3657
3658
3659/* exported interface documented in toolbar.h */
3661{
3662 size_t idn_url_l;
3663 char *idn_url_s = NULL;
3664 const char *url_text = NULL;
3665 GtkEntry *url_entry;
3666
3667 if (tb->items[URL_BAR_ITEM].button == NULL) {
3668 /* no toolbar item */
3669 return NSERROR_INVALID;
3670 }
3671 url_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(tb->items[URL_BAR_ITEM].button)));
3672
3673 if (nsoption_bool(display_decoded_idn) == true) {
3674 if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK) {
3675 idn_url_s = NULL;
3676 }
3677 url_text = idn_url_s;
3678 }
3679 if (url_text == NULL) {
3680 url_text = nsurl_access(url);
3681 }
3682
3683 if (strcmp(url_text, gtk_entry_get_text(url_entry)) != 0) {
3684 /* The URL bar content has changed, we need to update it */
3685 gint startpos, endpos;
3686 bool was_selected;
3687 gtk_editable_get_selection_bounds(GTK_EDITABLE(url_entry),
3688 &startpos, &endpos);
3689 was_selected = gtk_widget_is_focus(GTK_WIDGET(url_entry)) &&
3690 startpos == 0 &&
3691 endpos == gtk_entry_get_text_length(url_entry);
3692 gtk_entry_set_text(url_entry, url_text);
3693 if (was_selected && tb->loc_focus != LFS_IDLE) {
3694 gtk_widget_grab_focus(GTK_WIDGET(url_entry));
3695 if (tb->loc_focus == LFS_LAST) {
3696 tb->loc_focus = LFS_IDLE;
3697 }
3698 }
3699 }
3700
3701 if (idn_url_s != NULL) {
3702 free(idn_url_s);
3703 }
3704
3705 return NSERROR_OK;
3706}
3707
3708
3709/* exported interface documented in toolbar.h */
3710nserror
3712{
3713 GtkWidget *entry;
3714
3715 if (tb->items[WEBSEARCH_ITEM].button == NULL) {
3716 /* no toolbar item */
3717 return NSERROR_INVALID;
3718 }
3719
3720 entry = gtk_bin_get_child(GTK_BIN(tb->items[WEBSEARCH_ITEM].button));
3721
3722 if (pixbuf != NULL) {
3725 pixbuf);
3726 } else {
3730 }
3731
3732 return NSERROR_OK;
3733}
3734
3735
3736/* exported interface documented in toolbar.h */
3737nserror
3739 nsgtk_toolbar_button itemid)
3740{
3741 GtkWidget *widget;
3742
3743 /* ensure item id in range */
3744 if ((itemid < BACK_BUTTON) || (itemid >= PLACEHOLDER_BUTTON)) {
3745 return NSERROR_BAD_PARAMETER;
3746 }
3747
3748 if (tb->items[itemid].clicked == NULL) {
3749 return NSERROR_INVALID;
3750 }
3751
3752 /*
3753 * if item has a widget in the current toolbar use that as the
3754 * signal source otherwise use the toolbar widget itself.
3755 */
3756 if (tb->items[itemid].button != NULL) {
3757 widget = GTK_WIDGET(tb->items[itemid].button);
3758 } else {
3759 widget = GTK_WIDGET(tb->widget);
3760 }
3761
3762 tb->items[itemid].clicked(widget, tb);
3763
3764 return NSERROR_OK;
3765}
3766
3767
3768/* exported interface documented in toolbar.h */
3770{
3771 if (show) {
3772 gtk_widget_show(GTK_WIDGET(tb->widget));
3773 } else {
3774 gtk_widget_hide(GTK_WIDGET(tb->widget));
3775 }
3776 return NSERROR_OK;
3777}
3778
3779
3780/* exported interface documented in toolbar.h */
3782{
3783 nserror res;
3784
3785 /* setup item locations based on user config */
3787 if (res != NSERROR_OK) {
3788 return res;
3789 }
3790
3791 /* populate toolbar widget */
3793 if (res != NSERROR_OK) {
3794 return res;
3795 }
3796
3797 /* ensure icon sizes and text labels on toolbar are set */
3798 res = nsgtk_toolbar_restyle(tb);
3799 if (res != NSERROR_OK) {
3800 return res;
3801 }
3802
3803 res = toolbar_connect_signals(tb);
3804
3805 return res;
3806}
3807
3808/**
3809 * Find the correct location for popping up a window for the chosen item.
3810 *
3811 * \param tb The toolbar to select from
3812 * \param item_idx The toolbar item to select from
3813 * \param out_x Filled with an appropriate X coordinate
3814 * \param out_y Filled with an appropriate Y coordinate
3815 */
3816static nserror
3818 int item_idx,
3819 int *out_x,
3820 int *out_y)
3821{
3822 struct nsgtk_toolbar_item *item = &tb->items[item_idx];
3823 GtkWidget *widget = GTK_WIDGET(item->button);
3824 GtkAllocation alloc;
3825 gint rootx, rooty, x, y;
3826
3827 switch (item_idx) {
3828 case URL_BAR_ITEM:
3829 widget = GTK_WIDGET(gtk_bin_get_child(GTK_BIN(item->button)));
3830 break;
3831 default:
3832 /* Nothing to do here */
3833 break;
3834 }
3835
3836 nsgtk_widget_get_allocation(widget, &alloc);
3837
3838 if (gtk_widget_translate_coordinates(widget,
3839 gtk_widget_get_toplevel(widget),
3840 0,
3841 alloc.height - 1,
3842 &x, &y) != TRUE) {
3843 return NSERROR_UNKNOWN;
3844 }
3845
3846 gtk_window_get_position(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
3847 &rootx, &rooty);
3848
3849 *out_x = rootx + x + 4;
3850 *out_y = rooty + y + 4;
3851
3852 return NSERROR_OK;
3853}
3854
3856 struct nsgtk_pi_window *win)
3857{
3858 nserror res;
3859 int x, y;
3860
3862 if (res != NSERROR_OK) {
3863 return res;
3864 }
3865
3867
3868 return NSERROR_OK;
3869}
3870
3871/* exported interface documented in toolbar.h */
3873{
3874 nserror res;
3875 int x, y;
3876
3878 if (res != NSERROR_OK) {
3879 return res;
3880 }
3881
3883
3884 return NSERROR_OK;
3885}
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:1430
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:376
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:1072
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:382
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:311
Cookies (interface).
nserror nsgtk_warning(const char *warning, const char *detail)
Warn the user of an event.
Definition: gui.c:96
GdkPixbuf * favicon_pixbuf
favicon default pixbuf
Definition: gui.c:84
char * nsgtk_config_home
Directory where all configuration files are held.
Definition: gui.c:81
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:3738
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:3150
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:2880
nserror nsgtk_toolbar_restyle(struct nsgtk_toolbar *tb)
Update toolbar style and size based on current settings.
Definition: toolbar.c:3503
static nserror toolbar_connect_signal(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid)
connect signal handlers to a gtk toolbar item
Definition: toolbar.c:3312
static gboolean history_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for history tool bar item clicked signal
Definition: toolbar.c:2953
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:3711
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:3379
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:3660
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:3027
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:2967
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:3046
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:2925
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:3133
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:3255
nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, struct nsgtk_pi_window *win)
position the page info window appropriately
Definition: toolbar.c:3855
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:3208
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:3090
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:3112
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:3408
nserror nsgtk_toolbar_position_local_history(struct nsgtk_toolbar *tb)
position the local history window appropriately
Definition: toolbar.c:3872
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:3445
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:3431
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:3605
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:3008
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:3769
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:3817
static gboolean addbookmarks_button_clicked_cb(GtkWidget *widget, gpointer data)
handler for add bookmark tool bar item clicked signal
Definition: toolbar.c:2987
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:3781
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:3548
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:3069
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:3286
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:1621
nserror nsgtk_window_update_all(void)
Every window will have its tab, toolbar and drawing area updated.
Definition: window.c:1666
nserror nsgtk_window_toolbar_update(void)
every window will have its toolbar updated to reflect user settings
Definition: window.c:1693
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:401
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:263
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:256
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:251
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:978
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:161
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:298
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:786
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:331
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:313
#define nsoption_set_int(OPTION, VALUE)
set an integer option in the default table
Definition: nsoption.h:348
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:372
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:304
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