From 01084912c415412a57426fa70fac88c26e4ff0ad Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 20 Sep 2019 17:31:16 +0100 Subject: improve how toolbar contents customisation is stored in user options --- frontends/gtk/gui.c | 4 + frontends/gtk/options.h | 9 +- frontends/gtk/toolbar.c | 235 ++++++++++++++++++++++++++++-------------------- 3 files changed, 147 insertions(+), 101 deletions(-) diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c index a87ef7281..21d146c41 100644 --- a/frontends/gtk/gui.c +++ b/frontends/gtk/gui.c @@ -249,6 +249,10 @@ static nserror set_defaults(struct nsoption_s *defaults) break; } + /* set default items in toolbar */ + nsoption_set_charp(toolbar_items, + strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu")); + return NSERROR_OK; } diff --git a/frontends/gtk/options.h b/frontends/gtk/options.h index 018a448be..483a766a0 100644 --- a/frontends/gtk/options.h +++ b/frontends/gtk/options.h @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -#ifndef _NETSURF_GTK_OPTIONS_H_ -#define _NETSURF_GTK_OPTIONS_H_ +#ifndef NETSURF_GTK_OPTIONS_H_ +#define NETSURF_GTK_OPTIONS_H_ /* currently nothing here */ @@ -72,4 +72,7 @@ NSOPTION_INTEGER(developer_view, 0) NSOPTION_INTEGER(position_tab, 0) /* Toolbar customisation */ -NSOPTION_STRING(toolbar_order, NULL) +NSOPTION_STRING(toolbar_items, NULL) + +/* The menu and tool bars that are shown */ +NSOPTION_STRING(toolbar_show, NULL) diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c index 5fa373bd1..007a8fe2b 100644 --- a/frontends/gtk/toolbar.c +++ b/frontends/gtk/toolbar.c @@ -106,17 +106,41 @@ * toolbar item context */ struct nsgtk_toolbar_item { + + /** + * GTK widget in the toolbar + */ GtkToolItem *button; - int location; /* in toolbar */ + + /** + * location index in toolbar + */ + int location; + + /** + * if the item is currently sensitive in the toolbar + */ bool sensitivity; /** - * button clicked handler + * textural name used in serialising items + */ + const char *name; + + /** + * button clicked on toolbar handler + */ + gboolean (*clicked)(GtkWidget *widget, gpointer data); + + /** + * handler when dragging from customisation toolbox to toolbar */ - gboolean (*bhandler)(GtkWidget *widget, gpointer data); + void *dataplus; - void *dataplus; /* customisation -> toolbar */ - void *dataminus; /* customisation -> store */ + /** + * handler when dragging from toolbar to customisation toolbox + */ + void *dataminus; }; @@ -499,44 +523,80 @@ static GtkTargetEntry target_entry = { }; +/** + * find the toolbar item with a given location. + * + * \param tb the toolbar instance + * \param locaction the location to search for + * \return the item id for a location + */ +static nsgtk_toolbar_button +itemid_from_location(struct nsgtk_toolbar *tb, int location) +{ + int iidx; + for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) { + if (tb->items[iidx].location == location) { + break; + } + } + return iidx; +} + + /** * save toolbar settings to file */ static nserror -nsgtk_toolbar_customisation_save(struct nsgtk_toolbar_customisation *tbc) +nsgtk_toolbar_customisation_save(struct nsgtk_toolbar *tb) { + int iidx; /* item index */ + char *order; /* item ordering */ + char *start; /* start of next item name to be output */ + int orderlen = 0; /* length of item ordering */ + nsgtk_toolbar_button itemid; + int location; char *choices = NULL; - char *order; - int order_len; - int tbidx; - char *cur; - int plen; - order_len = PLACEHOLDER_BUTTON * 12; /* length of order buffer */ - order = malloc(order_len); + for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) { + if (tb->items[iidx].location != INACTIVE_LOCATION) { + orderlen += strlen(tb->items[iidx].name); + orderlen++; /* allow for separator */ + } + } + /* ensure there are some items to store */ + if (orderlen == 0) { + return NSERROR_INVALID; + } + + order = malloc(orderlen); if (order == NULL) { return NSERROR_NOMEM; } - cur = order; - for (tbidx = BACK_BUTTON; tbidx < PLACEHOLDER_BUTTON; tbidx++) { - plen = snprintf(cur, - order_len, - "%d;%d|", - tbidx, - tbc->toolbar.items[tbidx].location); - if (plen == order_len) { - /* ran out of space, bail early */ - NSLOG(netsurf, INFO, - "toolbar ordering exceeded available space"); + start = order; + + for (location = BACK_BUTTON; + location < PLACEHOLDER_BUTTON; + location++) { + itemid = itemid_from_location(tb, location); + if (itemid == PLACEHOLDER_BUTTON) { + /* no more filled locations */ + break; + } + start += snprintf(start, + orderlen - (start - order), + "%s/", + tb->items[itemid].name); + + if ((start - order) >= orderlen) { break; } - cur += plen; - order_len -= plen; } - nsoption_set_charp(toolbar_order, order); + order[orderlen - 1] = 0; + + nsoption_set_charp(toolbar_items, order); /* ensure choices are saved */ netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices"); @@ -549,26 +609,6 @@ nsgtk_toolbar_customisation_save(struct nsgtk_toolbar_customisation *tbc) } -/** - * find the toolbar item with a given location. - * - * \param tb the toolbar instance - * \param locaction the location to search for - * \return the item id for a location - */ -static nsgtk_toolbar_button -itemid_from_location(struct nsgtk_toolbar *tb, int location) -{ - int iidx; - for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) { - if (tb->items[iidx].location == location) { - break; - } - } - return iidx; -} - - /** * connect signals to a toolbar item in a customisation toolbar * @@ -861,56 +901,54 @@ nsgtk_browser_window_create(struct browser_window *bw, bool intab) static nserror apply_user_button_customisation(struct nsgtk_toolbar *tb) { - int i, ii; - char *buffer; - char *buffer1, *subbuffer, *ptr = NULL, *pter = NULL; + const char *tbitems; /* item order user config */ + const char *start; + const char *end; + int iidx; /* item index */ + int location = 0; /* location index */ /* set all button locations to inactive */ - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - tb->items[i].location = INACTIVE_LOCATION; + for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) { + tb->items[iidx].location = INACTIVE_LOCATION; } - /* if no user config is present apply the defaults */ - if (nsoption_charp(toolbar_order) == NULL) { - tb->items[BACK_BUTTON].location = 0; - tb->items[HISTORY_BUTTON].location = 1; - tb->items[FORWARD_BUTTON].location = 2; - tb->items[STOP_BUTTON].location = 3; - tb->items[RELOAD_BUTTON].location = 4; - tb->items[URL_BAR_ITEM].location = 5; - tb->items[WEBSEARCH_ITEM].location = 6; - tb->items[THROBBER_ITEM].location = 7; - - return NSERROR_OK; + tbitems = nsoption_charp(toolbar_items); + if (tbitems == NULL) { + tbitems = ""; } - buffer = strdup(nsoption_charp(toolbar_order)); - if (buffer == NULL) { - return NSERROR_NOMEM; - } + end = tbitems; + while (*end != 0) { + start = end; + while ((*end != 0) && (*end !='/')) { + end++; + } - i = BACK_BUTTON; - ii = BACK_BUTTON; - buffer1 = strtok_r(buffer, "|", &ptr); - while (buffer1 != NULL) { - subbuffer = strtok_r(buffer1, ";", &pter); - if (subbuffer != NULL) { - i = atoi(subbuffer); - subbuffer = strtok_r(NULL, ";", &pter); - if (subbuffer != NULL) { - ii = atoi(subbuffer); - if ((i >= BACK_BUTTON) && - (i < PLACEHOLDER_BUTTON) && - (ii >= -1) && - (ii < PLACEHOLDER_BUTTON)) { - tb->items[i].location = ii; - } + for (iidx = BACK_BUTTON; iidx < PLACEHOLDER_BUTTON; iidx++) { + if (strncmp(tb->items[iidx].name, start, end - start) == 0) { + tb->items[iidx].location = location++; + break; } } - buffer1 = strtok_r(NULL, "|", &ptr); + + if (*end == '/') { + end++; + } + } + + if (location == 0) { + /* completely failed to create any buttons so use defaults */ + tb->items[BACK_BUTTON].location = location++; + tb->items[HISTORY_BUTTON].location = location++; + tb->items[FORWARD_BUTTON].location = location++; + tb->items[RELOADSTOP_BUTTON].location = location++; + tb->items[URL_BAR_ITEM].location = location++; + tb->items[WEBSEARCH_ITEM].location = location++; + tb->items[OPENMENU_BUTTON].location = location++; + tb->items[THROBBER_ITEM].location = location++; } - free(buffer); + return NSERROR_OK; } @@ -1378,7 +1416,7 @@ customisation_apply_clicked_cb(GtkWidget *widget, gpointer data) tbc = (struct nsgtk_toolbar_customisation *)data; /* save state to file, update toolbars for all windows */ - nsgtk_toolbar_customisation_save(tbc); + nsgtk_toolbar_customisation_save(&tbc->toolbar); nsgtk_window_toolbar_update(); gtk_widget_destroy(tbc->container); @@ -3047,17 +3085,18 @@ toolbar_item_create(nsgtk_toolbar_button id, struct nsgtk_toolbar_item *item) /* set item defaults from macro */ switch (id) { #define TOOLBAR_ITEM_b(name) \ - item->bhandler = name##_button_clicked_cb; + item->clicked = name##_button_clicked_cb; #define TOOLBAR_ITEM_y(name) \ - item->bhandler = name##_button_clicked_cb; + item->clicked = name##_button_clicked_cb; #define TOOLBAR_ITEM_n(name) \ - item->bhandler = NULL; -#define TOOLBAR_ITEM(identifier, name, snstvty, clicked, activate, label, iconame) \ + item->clicked = NULL; +#define TOOLBAR_ITEM(identifier, iname, snstvty, clicked, activate, label, iconame) \ case identifier: \ + item->name = #iname; \ item->sensitivity = snstvty; \ - item->dataplus = nsgtk_toolbar_##name##_data_plus; \ - item->dataminus = nsgtk_toolbar_##name##_data_minus; \ - TOOLBAR_ITEM_ ## clicked(name) \ + item->dataplus = nsgtk_toolbar_##iname##_data_plus; \ + item->dataminus = nsgtk_toolbar_##iname##_data_minus; \ + TOOLBAR_ITEM_ ## clicked(iname) \ break; #include "gtk/toolbar_items.h" #undef TOOLBAR_ITEM_y @@ -3185,10 +3224,10 @@ toolbar_connect_signal(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid) break; default: - if ((item->bhandler != NULL) && (item->button != NULL)) { + if ((item->clicked != NULL) && (item->button != NULL)) { g_signal_connect(item->button, "clicked", - G_CALLBACK(item->bhandler), + G_CALLBACK(item->clicked), tb); } break; @@ -3475,7 +3514,7 @@ nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb, return NSERROR_BAD_PARAMETER; } - if (tb->items[itemid].bhandler == NULL) { + if (tb->items[itemid].clicked == NULL) { return NSERROR_INVALID; } @@ -3489,7 +3528,7 @@ nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb, widget = GTK_WIDGET(tb->widget); } - tb->items[itemid].bhandler(widget, tb); + tb->items[itemid].clicked(widget, tb); return NSERROR_OK; } -- cgit v1.2.3