summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2019-09-20 17:31:16 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2019-09-21 10:53:41 +0100
commitcbb818aa64b21e20954d06a4c5374a065d61088f (patch)
treeeafb40ff1b55a4c0b256ab44663a6bb6b2df3bbe
parent9b03d6ba6372298ad4df171003d35d54fe0c772c (diff)
downloadnetsurf-cbb818aa64b21e20954d06a4c5374a065d61088f.tar.gz
netsurf-cbb818aa64b21e20954d06a4c5374a065d61088f.tar.bz2
improve how toolbar contents customisation is stored in user options
-rw-r--r--frontends/gtk/gui.c4
-rw-r--r--frontends/gtk/options.h9
-rw-r--r--frontends/gtk/toolbar.c235
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 <http://www.gnu.org/licenses/>.
*/
-#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;
};
@@ -500,43 +524,79 @@ 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");
@@ -550,26 +610,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
*
* \param tb The 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;
}