From 997e8999d5a3a496a81d45b37f723d5bc539f5c4 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 12 Apr 2015 01:12:43 +0100 Subject: Refactor GTK toolbar handling to correctly cope with text labels --- gtk/preferences.c | 36 +- gtk/res/tabcontents.gtk3.ui | 16 +- gtk/scaffolding.c | 84 ++- gtk/scaffolding.h | 1 + gtk/toolbar.c | 1288 +++++++++++++++++++++---------------------- 5 files changed, 707 insertions(+), 718 deletions(-) (limited to 'gtk') diff --git a/gtk/preferences.c b/gtk/preferences.c index 7348afdc9..ec09fe766 100644 --- a/gtk/preferences.c +++ b/gtk/preferences.c @@ -861,39 +861,9 @@ nsgtk_preferences_comboButtonType_changed(GtkComboBox *widget, current = nsgtk_scaffolding_iterate(NULL); while (current != NULL) { nsgtk_scaffolding_reset_offset(current); - switch(nsoption_int(button_type)) { - /* value of 0 is reserved for 'unset' */ - case 1: - gtk_toolbar_set_style( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_TOOLBAR_ICONS); - gtk_toolbar_set_icon_size( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_ICON_SIZE_SMALL_TOOLBAR); - break; - case 2: - gtk_toolbar_set_style( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_TOOLBAR_ICONS); - gtk_toolbar_set_icon_size( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_ICON_SIZE_LARGE_TOOLBAR); - break; - case 3: - gtk_toolbar_set_style( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_TOOLBAR_BOTH); - gtk_toolbar_set_icon_size( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_ICON_SIZE_LARGE_TOOLBAR); - break; - case 4: - gtk_toolbar_set_style( - GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)), - GTK_TOOLBAR_TEXT); - default: - break; - } + + nsgtk_scaffolding_toolbars(current, nsoption_int(button_type)); + current = nsgtk_scaffolding_iterate(current); } } diff --git a/gtk/res/tabcontents.gtk3.ui b/gtk/res/tabcontents.gtk3.ui index 02de1bff1..23328b3b7 100644 --- a/gtk/res/tabcontents.gtk3.ui +++ b/gtk/res/tabcontents.gtk3.ui @@ -47,19 +47,6 @@ 1 - - - True - False - 2 - - - 1 - 1 - 1 - 1 - - True @@ -98,5 +85,8 @@ 1 + + + diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 2b30a3ed7..51f042443 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -1969,6 +1969,61 @@ static void nsgtk_scaffolding_initial_sensitivity(struct nsgtk_scaffolding *g) gtk_widget_set_sensitive(GTK_WIDGET(g->menu_bar->view_submenu->images_menuitem), FALSE); } + +void nsgtk_scaffolding_toolbars(struct nsgtk_scaffolding *g, int tbi) +{ + switch (tbi) { + /* case 0 is 'unset' [from fresh install / clearing options] + * see above */ + + case 1: /* Small icons */ + /* main toolbar */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), + GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->tool_bar), + GTK_ICON_SIZE_SMALL_TOOLBAR); + /* search toolbar */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->search->bar), + GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->search->bar), + GTK_ICON_SIZE_SMALL_TOOLBAR); + break; + + case 2: /* Large icons */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), + GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->tool_bar), + GTK_ICON_SIZE_LARGE_TOOLBAR); + /* search toolbar */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->search->bar), + GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->search->bar), + GTK_ICON_SIZE_LARGE_TOOLBAR); + break; + + case 3: /* Large icons with text */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), + GTK_TOOLBAR_BOTH); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->tool_bar), + GTK_ICON_SIZE_LARGE_TOOLBAR); + /* search toolbar */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->search->bar), + GTK_TOOLBAR_BOTH); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->search->bar), + GTK_ICON_SIZE_LARGE_TOOLBAR); + break; + + case 4: /* Text icons only */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), + GTK_TOOLBAR_TEXT); + /* search toolbar */ + gtk_toolbar_set_style(GTK_TOOLBAR(g->search->bar), + GTK_TOOLBAR_TEXT); + default: + break; + } +} + /* exported interface documented in gtk/scaffolding.h */ struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) { @@ -2104,34 +2159,7 @@ struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) } } - switch (nsoption_int(button_type)) { - /* case 0 is 'unset' [from fresh install / clearing options] - * see above */ - - case 1: /* Small icons */ - gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), - GTK_TOOLBAR_ICONS); - gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->tool_bar), - GTK_ICON_SIZE_SMALL_TOOLBAR); - break; - case 2: /* Large icons */ - gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), - GTK_TOOLBAR_ICONS); - gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->tool_bar), - GTK_ICON_SIZE_LARGE_TOOLBAR); - break; - case 3: /* Large icons with text */ - gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), - GTK_TOOLBAR_BOTH); - gtk_toolbar_set_icon_size(GTK_TOOLBAR(g->tool_bar), - GTK_ICON_SIZE_LARGE_TOOLBAR); - break; - case 4: /* Text icons only */ - gtk_toolbar_set_style(GTK_TOOLBAR(g->tool_bar), - GTK_TOOLBAR_TEXT); - default: - break; - } + nsgtk_scaffolding_toolbars(g, nsoption_int(button_type)); gtk_toolbar_set_show_arrow(g->tool_bar, TRUE); gtk_widget_show_all(GTK_WIDGET(g->tool_bar)); diff --git a/gtk/scaffolding.h b/gtk/scaffolding.h index 730d4fc89..3fbad59db 100644 --- a/gtk/scaffolding.h +++ b/gtk/scaffolding.h @@ -247,5 +247,6 @@ nserror gui_window_set_url(struct gui_window *g, struct nsurl *url); void gui_window_start_throbber(struct gui_window *g); void gui_window_stop_throbber(struct gui_window *g); +void nsgtk_scaffolding_toolbars(struct nsgtk_scaffolding *g, int tbi); #endif /* NETSURF_GTK_SCAFFOLDING_H */ diff --git a/gtk/toolbar.c b/gtk/toolbar.c index 0a518a511..b6bf8d98a 100644 --- a/gtk/toolbar.c +++ b/gtk/toolbar.c @@ -67,333 +67,405 @@ possible into the store */ static struct nsgtk_toolbar_custom_store store; static struct nsgtk_toolbar_custom_store *window = &store; -static void nsgtk_toolbar_close(struct nsgtk_scaffolding *g); -static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g); -static void nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g); -static void nsgtk_toolbar_add_item_to_toolbar(struct nsgtk_scaffolding *g, int i, struct nsgtk_theme *theme); -static bool nsgtk_toolbar_add_store_widget(GtkWidget *widget); -static gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *context, - gint x, gint y, guint time, gpointer data); -static gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data); -static gboolean nsgtk_toolbar_action(GtkWidget *widget, GdkDragContext - *drag_context, gint x, gint y, guint time, gpointer data); -gboolean nsgtk_toolbar_store_action(GtkWidget *widget, GdkDragContext *gdc, - gint x, gint y, guint time, gpointer data); -static gboolean nsgtk_toolbar_move_complete(GtkWidget *widget, GdkDragContext - *gdc, gint x, gint y, GtkSelectionData *selection, guint info, - guint time, gpointer data); -static void nsgtk_toolbar_clear(GtkWidget *widget, GdkDragContext *gdc, guint - time, gpointer data); -static gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, - gpointer data); -static gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data); -static gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data); -static gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data); -static void nsgtk_toolbar_cast(struct nsgtk_scaffolding *g); -static GtkWidget *nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, - nsgtk_toolbar_button i, struct nsgtk_theme *theme); -static void nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, - nsgtk_toolbar_button i); +/** + * callback function to iterate toolbar's widgets + */ +static void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data) +{ + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + gtk_container_remove(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), + widget); +} + +/** + * connect temporary handler for toolbar edit events + * + * \param g The scaffolding + * \param bi The button index + */ static void nsgtk_toolbar_temp_connect(struct nsgtk_scaffolding *g, - nsgtk_toolbar_button i); -static void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data); -static nsgtk_toolbar_button nsgtk_toolbar_get_id_at_location( - struct nsgtk_scaffolding *g, int i); + nsgtk_toolbar_button bi) +{ + struct nsgtk_button_connect *bc; + + if (bi != URL_BAR_ITEM) { + bc = nsgtk_scaffolding_button(g, bi); + if ((bc->button != NULL) && (bc->dataminus != NULL)) { + g_signal_connect(bc->button, + "drag-data-get", + G_CALLBACK(bc->dataminus), + g); + } + } +} /** - * change behaviour of scaffoldings while editing toolbar + * get scaffolding button index of button at location * - * All buttons as well as window clicks are desensitized; then buttons - * in the front window are changed to movable buttons + * \return toolbar item id from location when there is an item at that logical + * location; else -1 */ -void nsgtk_toolbar_customization_init(struct nsgtk_scaffolding *g) +static nsgtk_toolbar_button +nsgtk_toolbar_get_id_at_location(struct nsgtk_scaffolding *g, int i) { - int i; - struct nsgtk_scaffolding *list; - edit_mode = true; + int q; + for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) { + if (nsgtk_scaffolding_button(g, q)->location == i) { + return q; + } + } + return -1; +} - list = nsgtk_scaffolding_iterate(NULL); - while (list) { - g_signal_handler_block(GTK_WIDGET( - nsgtk_window_get_layout( - nsgtk_scaffolding_top_level(list))), - nsgtk_window_get_signalhandler( - nsgtk_scaffolding_top_level(list), - NSGTK_WINDOW_SIGNAL_CLICK)); - g_signal_handler_block(GTK_WIDGET( - nsgtk_window_get_layout( - nsgtk_scaffolding_top_level(list))), - nsgtk_window_get_signalhandler( - nsgtk_scaffolding_top_level(list), - NSGTK_WINDOW_SIGNAL_REDRAW)); - nsgtk_widget_override_background_color( - GTK_WIDGET(nsgtk_window_get_layout( - nsgtk_scaffolding_top_level(list))), - GTK_STATE_NORMAL, 0, 0xEEEE, 0xEEEE, 0xEEEE); +/** + * widget factory for creation of toolbar item widgets + * \param g the reference scaffolding + * \param i the id of the widget + * \param theme the theme to make the widgets from + */ +static GtkWidget * +nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, + nsgtk_toolbar_button i, + struct nsgtk_theme *theme) +{ + GtkWidget *w = NULL; - if (list == g) { - list = nsgtk_scaffolding_iterate(list); - continue; + switch(i) { + +/* gtk_tool_button_new() accepts NULL args */ +#define MAKE_STOCKBUTTON(p, q) \ + case p##_BUTTON: { \ + GtkStockItem item; \ + char *label = NULL; \ + if (nsgtk_stock_lookup(q, &item) && \ + (item.label != NULL) && \ + ((label = remove_underscores(item.label, false)) != NULL)) { \ + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ + theme->image[p##_BUTTON]), label)); \ + free(label); \ + } else { \ + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ + theme->image[p##_BUTTON]), q)); \ + } \ + break; \ + } + + MAKE_STOCKBUTTON(HOME, NSGTK_STOCK_HOME) + MAKE_STOCKBUTTON(BACK, NSGTK_STOCK_GO_BACK) + MAKE_STOCKBUTTON(FORWARD, NSGTK_STOCK_GO_FORWARD) + MAKE_STOCKBUTTON(STOP, NSGTK_STOCK_STOP) + MAKE_STOCKBUTTON(RELOAD, NSGTK_STOCK_REFRESH) +#undef MAKE_STOCKBUTTON + + case HISTORY_BUTTON: + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( + theme->image[HISTORY_BUTTON]), "H")); + break; + + case URL_BAR_ITEM: { + GtkWidget *entry = nsgtk_entry_new(); + w = GTK_WIDGET(gtk_tool_item_new()); + + if ((entry == NULL) || (w == NULL)) { + warn_user(messages_get("NoMemory"), 0); + return NULL; } - /* set sensitive for all gui_windows save g */ - gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_window( - list)), FALSE); - list = nsgtk_scaffolding_iterate(list); + + nsgtk_entry_set_icon_from_pixbuf(entry, + GTK_ENTRY_ICON_PRIMARY, + favicon_pixbuf); + + gtk_container_add(GTK_CONTAINER(w), entry); + gtk_tool_item_set_expand(GTK_TOOL_ITEM(w), TRUE); + break; } - /* set sensitive for all of g save toolbar */ - gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_menu_bar(g)), - FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_notebook(g)), - FALSE); - /* set editable aspect for toolbar */ - gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), - nsgtk_toolbar_clear_toolbar, g); - nsgtk_toolbar_set_physical(g); - /* memorize button locations, set editable */ - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - window->buttonlocations[i] = nsgtk_scaffolding_button(g, i) - ->location; - if ((window->buttonlocations[i] == -1) || (i == URL_BAR_ITEM)) - continue; - gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( - nsgtk_scaffolding_button(g, i)->button), TRUE); - gtk_drag_source_set(GTK_WIDGET(nsgtk_scaffolding_button( - g, i)->button), GDK_BUTTON1_MASK, &entry, 1, - GDK_ACTION_COPY); - nsgtk_toolbar_temp_connect(g, i); + case THROBBER_ITEM: { + if ((nsgtk_throbber == NULL) || + (nsgtk_throbber->framedata == NULL) || + (nsgtk_throbber->framedata[0] == NULL)) { + return NULL; + } + + if (edit_mode) { + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( + gtk_image_new_from_pixbuf( + nsgtk_throbber->framedata[0])), + "[throbber]")); + } else { + GtkWidget *image; + + w = GTK_WIDGET(gtk_tool_item_new()); + + image = gtk_image_new_from_pixbuf(nsgtk_throbber->framedata[0]); + if (image != NULL) { + nsgtk_widget_set_alignment(image, + GTK_ALIGN_CENTER, + GTK_ALIGN_CENTER); + nsgtk_widget_set_margins(image, 3, 0); + + gtk_container_add(GTK_CONTAINER(w), image); + } + } + break; } - /* add move button listeners */ - g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), - "drag-drop", G_CALLBACK(nsgtk_toolbar_data), g); - g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), - "drag-data-received", G_CALLBACK( - nsgtk_toolbar_move_complete), g); - g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), - "drag-motion", G_CALLBACK(nsgtk_toolbar_action), g); - g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), - "drag-leave", G_CALLBACK( - nsgtk_toolbar_clear), g); + case WEBSEARCH_ITEM: { + if (edit_mode) + return GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( + nsgtk_image_new_from_stock(NSGTK_STOCK_FIND, + GTK_ICON_SIZE_LARGE_TOOLBAR)), + "[websearch]")); - /* set data types */ - gtk_drag_dest_set(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), - GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, - &entry, 1, GDK_ACTION_COPY); + GtkWidget *entry = nsgtk_entry_new(); - /* open toolbar window */ - nsgtk_toolbar_window_open(g); + w = GTK_WIDGET(gtk_tool_item_new()); + + if ((entry == NULL) || (w == NULL)) { + warn_user(messages_get("NoMemory"), 0); + return NULL; + } + + gtk_widget_set_size_request(entry, NSGTK_WEBSEARCH_WIDTH, -1); + + nsgtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, + NSGTK_STOCK_INFO); + + gtk_container_add(GTK_CONTAINER(w), entry); + break; + } + +/* gtk_tool_button_new accepts NULL args */ +#define MAKE_MENUBUTTON(p, q) \ + case p##_BUTTON: { \ + char *label = NULL; \ + label = remove_underscores(messages_get(#q), false); \ + w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ + theme->image[p##_BUTTON]), label)); \ + if (label != NULL) \ + free(label); \ + break; \ + } + + MAKE_MENUBUTTON(NEWWINDOW, gtkNewWindow) + MAKE_MENUBUTTON(NEWTAB, gtkNewTab) + MAKE_MENUBUTTON(OPENFILE, gtkOpenFile) + MAKE_MENUBUTTON(CLOSETAB, gtkCloseTab) + MAKE_MENUBUTTON(CLOSEWINDOW, gtkCloseWindow) + MAKE_MENUBUTTON(SAVEPAGE, gtkSavePage) + MAKE_MENUBUTTON(PRINTPREVIEW, gtkPrintPreview) + MAKE_MENUBUTTON(PRINT, gtkPrint) + MAKE_MENUBUTTON(QUIT, gtkQuitMenu) + MAKE_MENUBUTTON(CUT, gtkCut) + MAKE_MENUBUTTON(COPY, gtkCopy) + MAKE_MENUBUTTON(PASTE, gtkPaste) + MAKE_MENUBUTTON(DELETE, gtkDelete) + MAKE_MENUBUTTON(SELECTALL, gtkSelectAll) + MAKE_MENUBUTTON(PREFERENCES, gtkPreferences) + MAKE_MENUBUTTON(ZOOMPLUS, gtkZoomPlus) + MAKE_MENUBUTTON(ZOOMMINUS, gtkZoomMinus) + MAKE_MENUBUTTON(ZOOMNORMAL, gtkZoomNormal) + MAKE_MENUBUTTON(FULLSCREEN, gtkFullScreen) + MAKE_MENUBUTTON(VIEWSOURCE, gtkViewSource) + MAKE_MENUBUTTON(CONTENTS, gtkContents) + MAKE_MENUBUTTON(ABOUT, gtkAbout) + MAKE_MENUBUTTON(PDF, gtkPDF) + MAKE_MENUBUTTON(PLAINTEXT, gtkPlainText) + MAKE_MENUBUTTON(DRAWFILE, gtkDrawFile) + MAKE_MENUBUTTON(POSTSCRIPT, gtkPostScript) + MAKE_MENUBUTTON(FIND, gtkFind) + MAKE_MENUBUTTON(DOWNLOADS, gtkDownloads) + MAKE_MENUBUTTON(SAVEWINDOWSIZE, gtkSaveWindowSize) + MAKE_MENUBUTTON(TOGGLEDEBUGGING, gtkToggleDebugging) + MAKE_MENUBUTTON(SAVEBOXTREE, gtkDebugBoxTree) + MAKE_MENUBUTTON(SAVEDOMTREE, gtkDebugDomTree) + MAKE_MENUBUTTON(LOCALHISTORY, gtkLocalHistory) + MAKE_MENUBUTTON(GLOBALHISTORY, gtkGlobalHistory) + MAKE_MENUBUTTON(ADDBOOKMARKS, gtkAddBookMarks) + MAKE_MENUBUTTON(SHOWBOOKMARKS, gtkShowBookMarks) + MAKE_MENUBUTTON(SHOWCOOKIES, gtkShowCookies) + MAKE_MENUBUTTON(OPENLOCATION, gtkOpenLocation) + MAKE_MENUBUTTON(NEXTTAB, gtkNextTab) + MAKE_MENUBUTTON(PREVTAB, gtkPrevTab) + MAKE_MENUBUTTON(GUIDE, gtkGuide) + MAKE_MENUBUTTON(INFO, gtkUserInformation) +#undef MAKE_MENUBUTTON + + default: + break; + + } + return w; } /** - * create store window + * called when a widget is dropped onto the toolbar */ -void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g) +static gboolean +nsgtk_toolbar_data(GtkWidget *widget, + GdkDragContext *gdc, + gint x, + gint y, + guint time, + gpointer data) { - int x = 0, y = 0; - GError* error = NULL; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + int ind = gtk_toolbar_get_drop_index(nsgtk_scaffolding_toolbar(g), + x, y); + int q, i; + if (window->currentbutton == -1) + return TRUE; struct nsgtk_theme *theme = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); if (theme == NULL) { warn_user(messages_get("NoMemory"), 0); - nsgtk_toolbar_cancel_clicked(NULL, g); - return; - } - - window->glade = gtk_builder_new(); - if (!gtk_builder_add_from_file(window->glade, - glade_file_location->toolbar, - &error)) { - g_warning ("Couldn't load builder file: %s", error->message); - g_error_free (error); - warn_user(messages_get("NoMemory"), 0); - nsgtk_toolbar_cancel_clicked(NULL, g); - free(theme); - return; + return TRUE; } - - gtk_builder_connect_signals(window->glade, NULL); - - window->window = GTK_WIDGET(gtk_builder_get_object(window->glade, "toolbarwindow")); - if (window->window == NULL) { - warn_user(messages_get("NoMemory"), 0); - nsgtk_toolbar_cancel_clicked(NULL, g); - free(theme); - return; + if (nsgtk_scaffolding_button(g, window->currentbutton)->location + != -1) { + /* widget was already in the toolbar; so replace */ + if (nsgtk_scaffolding_button(g, window->currentbutton)-> + location < ind) + ind--; + gtk_container_remove(GTK_CONTAINER( + nsgtk_scaffolding_toolbar(g)), GTK_WIDGET( + nsgtk_scaffolding_button(g, + window->currentbutton)->button)); + /* 'move' all widgets further right than the original location, + * one place to the left in logical schema */ + for (i = nsgtk_scaffolding_button(g, window->currentbutton)-> + location + 1; i < PLACEHOLDER_BUTTON; i++) { + q = nsgtk_toolbar_get_id_at_location(g, i); + if (q == -1) + continue; + nsgtk_scaffolding_button(g, q)->location--; + } + nsgtk_scaffolding_button(g, window->currentbutton)-> + location = -1; } - - window->widgetvbox = GTK_WIDGET(gtk_builder_get_object(window->glade, "widgetvbox")); - if (window->widgetvbox == NULL) { - warn_user(messages_get("NoMemory"), 0); - nsgtk_toolbar_cancel_clicked(NULL, g); - free(theme); - return; + nsgtk_scaffolding_button(g, window->currentbutton)->button = + GTK_TOOL_ITEM(nsgtk_toolbar_make_widget(g, + window->currentbutton, theme)); + free(theme); + if (nsgtk_scaffolding_button(g, window->currentbutton)->button + == NULL) { + warn_user("NoMemory", 0); + return TRUE; } - - window->numberh = NSGTK_STORE_WIDTH; /* preset to width [in buttons] of */ - /* store to cause creation of a new toolbar */ - window->currentbutton = -1; - /* load toolbuttons */ - /* add toolbuttons to window */ - /* set event handlers */ - for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - if (i == URL_BAR_ITEM) - continue; - window->store_buttons[i] = - nsgtk_toolbar_make_widget(g, i, theme); - if (window->store_buttons[i] == NULL) { - warn_user(messages_get("NoMemory"), 0); + /* update logical schema */ + nsgtk_scaffolding_reset_offset(g); + /* 'move' all widgets further right than the new location, one place to + * the right in logical schema */ + for (i = PLACEHOLDER_BUTTON - 1; i >= ind; i--) { + q = nsgtk_toolbar_get_id_at_location(g, i); + if (q == -1) continue; - } - nsgtk_toolbar_add_store_widget(window->store_buttons[i]); - g_signal_connect(window->store_buttons[i], "drag-data-get", - G_CALLBACK( - nsgtk_scaffolding_button(g, i)->dataplus), g); + nsgtk_scaffolding_button(g, q)->location++; } - free(theme); - gtk_window_set_transient_for(GTK_WINDOW(window->window), - nsgtk_scaffolding_window(g)); - gtk_window_set_title(GTK_WINDOW(window->window), messages_get( - "gtkToolBarTitle")); - gtk_window_set_accept_focus(GTK_WINDOW(window->window), FALSE); - gtk_drag_dest_set(GTK_WIDGET(window->window), GTK_DEST_DEFAULT_MOTION | - GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY); - gtk_widget_show_all(window->window); - gtk_window_set_position(GTK_WINDOW(window->window), - GTK_WIN_POS_CENTER_ON_PARENT); - gtk_window_get_position(nsgtk_scaffolding_window(g), &x, &y); - gtk_window_move(GTK_WINDOW(window->window), x, y + 100); - g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->glade, "cancelbutton")), - "clicked", - G_CALLBACK(nsgtk_toolbar_cancel_clicked), - g); + nsgtk_scaffolding_button(g, window->currentbutton)->location = ind; + + /* complete action */ + GtkToolItem *current_button; + + current_button = GTK_TOOL_ITEM(nsgtk_scaffolding_button(g, window->currentbutton)->button); + + gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), current_button, ind); - g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->glade, "okbutton")), - "clicked", G_CALLBACK(nsgtk_toolbar_persist), g); - g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->glade, "resetbutton")), - "clicked", G_CALLBACK(nsgtk_toolbar_reset), g); - g_signal_connect(window->window, "delete-event", - G_CALLBACK(nsgtk_toolbar_delete), g); - g_signal_connect(window->window, "drag-drop", - G_CALLBACK(nsgtk_toolbar_store_return), g); - g_signal_connect(window->window, "drag-motion", - G_CALLBACK(nsgtk_toolbar_store_action), g); -} + gtk_tool_item_set_use_drag_window(current_button, TRUE); + gtk_drag_source_set(GTK_WIDGET(current_button), + GDK_BUTTON1_MASK, &entry, 1, + GDK_ACTION_COPY); + nsgtk_toolbar_temp_connect(g, window->currentbutton); + gtk_widget_show_all(GTK_WIDGET(current_button)); + + + window->currentbutton = -1; -/** - * when titlebar / alt-F4 window close event happens - */ -gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, - gpointer data) -{ - edit_mode = false; - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - /* reset g->buttons->location */ - for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - nsgtk_scaffolding_button(g, i)->location = - window->buttonlocations[i]; - } - nsgtk_toolbar_set_physical(g); - nsgtk_toolbar_connect_all(g); - nsgtk_toolbar_close(g); - nsgtk_scaffolding_set_sensitivity(g); - gtk_widget_destroy(window->window); return TRUE; } /** - * when cancel button is clicked + * connected to toolbutton drop; perhaps one day it'll work properly so it may + * replace the global current_button */ -gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data) +static gboolean +nsgtk_toolbar_move_complete(GtkWidget *widget, + GdkDragContext *gdc, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time, + gpointer data) { - edit_mode = false; - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - /* reset g->buttons->location */ - for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - nsgtk_scaffolding_button(g, i)->location = - window->buttonlocations[i]; - } - nsgtk_toolbar_set_physical(g); - nsgtk_toolbar_connect_all(g); - nsgtk_toolbar_close(g); - nsgtk_scaffolding_set_sensitivity(g); - gtk_widget_destroy(window->window); - return TRUE; + return FALSE; } /** - * when 'save settings' button is clicked + * called when hovering an item above the toolbar */ -gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data) +static gboolean +nsgtk_toolbar_action(GtkWidget *widget, GdkDragContext *gdc, gint x, + gint y, guint time, gpointer data) { - edit_mode = false; struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - /* save state to file, update toolbars for all windows */ - nsgtk_toolbar_customization_save(g); - nsgtk_toolbar_cast(g); - nsgtk_toolbar_set_physical(g); - nsgtk_toolbar_close(g); - gtk_widget_destroy(window->window); - return TRUE; + GtkToolItem *item = gtk_tool_button_new(NULL, NULL); + if (item != NULL) + gtk_toolbar_set_drop_highlight_item( + nsgtk_scaffolding_toolbar(g), + GTK_TOOL_ITEM(item), + gtk_toolbar_get_drop_index( + nsgtk_scaffolding_toolbar(g), x, y)); + return FALSE; } /** - * when 'reload defaults' button is clicked + * called when hovering stops */ -gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data) +static void +nsgtk_toolbar_clear(GtkWidget *widget, GdkDragContext *gdc, guint time, + gpointer data) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - int i; - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) - nsgtk_scaffolding_button(g, i)->location = - (i <= THROBBER_ITEM) ? i : -1; - nsgtk_toolbar_set_physical(g); - for (i = BACK_BUTTON; i <= THROBBER_ITEM; i++) { - if (i == URL_BAR_ITEM) - continue; - gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( - nsgtk_scaffolding_button(g, i)->button), TRUE); - gtk_drag_source_set(GTK_WIDGET( - nsgtk_scaffolding_button(g, i)->button), - GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_COPY); - nsgtk_toolbar_temp_connect(g, i); - } - return TRUE; + gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(widget), NULL, 0); } /** - * set toolbar logical -> physical; physically visible toolbar buttons are made - * to correspond to the logically stored schema in terms of location - * visibility etc + * add item to toolbar. + * + * the function should be called, when multiple items are being added, + * in ascending order. + * + * \param g the scaffolding whose toolbar an item is added to. + * \param i the location in the toolbar. + * \param theme The theme in use. */ -void nsgtk_toolbar_set_physical(struct nsgtk_scaffolding *g) +static void +nsgtk_toolbar_add_item_to_toolbar(struct nsgtk_scaffolding *g, int i, + struct nsgtk_theme *theme) { - int i; - struct nsgtk_theme *theme = - nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); - if (theme == NULL) { - warn_user(messages_get("NoMemory"), 0); - return; - } - /* simplest is to clear the toolbar then reload it from memory */ - gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), - nsgtk_toolbar_clear_toolbar, g); - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) - nsgtk_toolbar_add_item_to_toolbar(g, i, theme); - gtk_widget_show_all(GTK_WIDGET(nsgtk_scaffolding_toolbar(g))); - free(theme); + int q; + for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) + if (nsgtk_scaffolding_button(g, q)->location == i) { + nsgtk_scaffolding_button(g, q)->button = GTK_TOOL_ITEM( + nsgtk_toolbar_make_widget(g, q, + theme)); + gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), + nsgtk_scaffolding_button(g, q)->button, + i); + break; + } } /** * cleanup code physical update of all toolbars; resensitize * \param g the 'front' scaffolding that called customize */ -void nsgtk_toolbar_close(struct nsgtk_scaffolding *g) +static void nsgtk_toolbar_close(struct nsgtk_scaffolding *g) { int i; struct nsgtk_scaffolding *list; - struct nsgtk_theme *theme; + struct nsgtk_theme *theme; list = nsgtk_scaffolding_iterate(NULL); while (list) { @@ -447,44 +519,29 @@ void nsgtk_toolbar_close(struct nsgtk_scaffolding *g) } /** - * callback function to iterate toolbar's widgets + * when cancel button is clicked */ -void nsgtk_toolbar_clear_toolbar(GtkWidget *widget, gpointer data) +static gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data) { + edit_mode = false; struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - gtk_container_remove(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), widget); -} - -/** - * add item to toolbar. - * - * the function should be called, when multiple items are being added, - * in ascending order. - * - * \param g the scaffolding whose toolbar an item is added to. - * \param i the location in the toolbar. - * \param theme The theme in use. - */ -void nsgtk_toolbar_add_item_to_toolbar(struct nsgtk_scaffolding *g, int i, - struct nsgtk_theme *theme) -{ - int q; - for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) - if (nsgtk_scaffolding_button(g, q)->location == i) { - nsgtk_scaffolding_button(g, q)->button = GTK_TOOL_ITEM( - nsgtk_toolbar_make_widget(g, q, - theme)); - gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), - nsgtk_scaffolding_button(g, q)->button, - i); - break; - } + /* reset g->buttons->location */ + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + nsgtk_scaffolding_button(g, i)->location = + window->buttonlocations[i]; + } + nsgtk_toolbar_set_physical(g); + nsgtk_toolbar_connect_all(g); + nsgtk_toolbar_close(g); + nsgtk_scaffolding_set_sensitivity(g); + gtk_widget_destroy(window->window); + return TRUE; } /** * physically add widgets to store window */ -bool nsgtk_toolbar_add_store_widget(GtkWidget *widget) +static bool nsgtk_toolbar_add_store_widget(GtkWidget *widget) { if (window->numberh >= NSGTK_STORE_WIDTH) { window->currentbar = gtk_toolbar_new(); @@ -512,102 +569,116 @@ bool nsgtk_toolbar_add_store_widget(GtkWidget *widget) } /** - * called when a widget is dropped onto the toolbar + * save toolbar settings to file */ -gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *gdc, gint x, - gint y, guint time, gpointer data) +static void nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - int ind = gtk_toolbar_get_drop_index(nsgtk_scaffolding_toolbar(g), - x, y); - int q, i; - if (window->currentbutton == -1) - return TRUE; - struct nsgtk_theme *theme = - nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); - if (theme == NULL) { - warn_user(messages_get("NoMemory"), 0); - return TRUE; - } - if (nsgtk_scaffolding_button(g, window->currentbutton)->location - != -1) { - /* widget was already in the toolbar; so replace */ - if (nsgtk_scaffolding_button(g, window->currentbutton)-> - location < ind) - ind--; - gtk_container_remove(GTK_CONTAINER( - nsgtk_scaffolding_toolbar(g)), GTK_WIDGET( - nsgtk_scaffolding_button(g, - window->currentbutton)->button)); - /* 'move' all widgets further right than the original location, - * one place to the left in logical schema */ - for (i = nsgtk_scaffolding_button(g, window->currentbutton)-> - location + 1; i < PLACEHOLDER_BUTTON; i++) { - q = nsgtk_toolbar_get_id_at_location(g, i); - if (q == -1) - continue; - nsgtk_scaffolding_button(g, q)->location--; - } - nsgtk_scaffolding_button(g, window->currentbutton)-> - location = -1; - } - nsgtk_scaffolding_button(g, window->currentbutton)->button = - GTK_TOOL_ITEM(nsgtk_toolbar_make_widget(g, - window->currentbutton, theme)); - free(theme); - if (nsgtk_scaffolding_button(g, window->currentbutton)->button - == NULL) { - warn_user("NoMemory", 0); - return TRUE; + int i; + FILE *f = fopen(toolbar_indices_file_location, "w"); + if (f == NULL){ + warn_user("gtkFileError", toolbar_indices_file_location); + return; } - /* update logical schema */ - nsgtk_scaffolding_reset_offset(g); - /* 'move' all widgets further right than the new location, one place to - * the right in logical schema */ - for (i = PLACEHOLDER_BUTTON - 1; i >= ind; i--) { - q = nsgtk_toolbar_get_id_at_location(g, i); - if (q == -1) - continue; - nsgtk_scaffolding_button(g, q)->location++; + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + fprintf(f, "%d;%d|", i, nsgtk_scaffolding_button(g, i)->location); } - nsgtk_scaffolding_button(g, window->currentbutton)->location = ind; - - /* complete action */ - GtkToolItem *current_button; - - current_button = GTK_TOOL_ITEM(nsgtk_scaffolding_button(g, window->currentbutton)->button); - - gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), current_button, ind); + fclose(f); +} - gtk_tool_item_set_use_drag_window(current_button, TRUE); - gtk_drag_source_set(GTK_WIDGET(current_button), - GDK_BUTTON1_MASK, &entry, 1, - GDK_ACTION_COPY); - nsgtk_toolbar_temp_connect(g, window->currentbutton); - gtk_widget_show_all(GTK_WIDGET(current_button)); +/** + * cast toolbar settings to all scaffoldings referenced from the global linked + * list of gui_windows + */ +static void nsgtk_toolbar_cast(struct nsgtk_scaffolding *g) +{ + int i; + struct nsgtk_scaffolding *list; + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + window->buttonlocations[i] = + ((nsgtk_scaffolding_button(g, i)->location + >= -1) && + (nsgtk_scaffolding_button(g, i)->location + < PLACEHOLDER_BUTTON)) ? + nsgtk_scaffolding_button(g, i)->location : -1; + } - window->currentbutton = -1; + list = nsgtk_scaffolding_iterate(NULL); + while (list) { + if (list != g) + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) + nsgtk_scaffolding_button(list, i)->location = + window->buttonlocations[i]; + list = nsgtk_scaffolding_iterate(list); + } +} +/** + * when 'save settings' button is clicked + */ +static gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data) +{ + edit_mode = false; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + /* save state to file, update toolbars for all windows */ + nsgtk_toolbar_customization_save(g); + nsgtk_toolbar_cast(g); + nsgtk_toolbar_set_physical(g); + nsgtk_toolbar_close(g); + gtk_widget_destroy(window->window); return TRUE; } /** - * connected to toolbutton drop; perhaps one day it'll work properly so it may - * replace the global current_button + * when 'reload defaults' button is clicked */ +static gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data) +{ + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + int i; + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) + nsgtk_scaffolding_button(g, i)->location = + (i <= THROBBER_ITEM) ? i : -1; + nsgtk_toolbar_set_physical(g); + for (i = BACK_BUTTON; i <= THROBBER_ITEM; i++) { + if (i == URL_BAR_ITEM) + continue; + gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( + nsgtk_scaffolding_button(g, i)->button), TRUE); + gtk_drag_source_set(GTK_WIDGET( + nsgtk_scaffolding_button(g, i)->button), + GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_COPY); + nsgtk_toolbar_temp_connect(g, i); + } + return TRUE; +} -gboolean nsgtk_toolbar_move_complete(GtkWidget *widget, GdkDragContext *gdc, - gint x, gint y, GtkSelectionData *selection, guint info, - guint time, gpointer data) +/** + * when titlebar / alt-F4 window close event happens + */ +static gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, + gpointer data) { - return FALSE; + edit_mode = false; + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + /* reset g->buttons->location */ + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + nsgtk_scaffolding_button(g, i)->location = + window->buttonlocations[i]; + } + nsgtk_toolbar_set_physical(g); + nsgtk_toolbar_connect_all(g); + nsgtk_toolbar_close(g); + nsgtk_scaffolding_set_sensitivity(g); + gtk_widget_destroy(window->window); + return TRUE; } /** * called when a widget is dropped onto the store window */ -gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, +static gboolean +nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; @@ -639,225 +710,226 @@ gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, gtk_drag_finish(gdc, TRUE, TRUE, time); return FALSE; } -/** - * called when hovering an item above the toolbar - */ -gboolean nsgtk_toolbar_action(GtkWidget *widget, GdkDragContext *gdc, gint x, - gint y, guint time, gpointer data) -{ - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - GtkToolItem *item = gtk_tool_button_new(NULL, NULL); - if (item != NULL) - gtk_toolbar_set_drop_highlight_item( - nsgtk_scaffolding_toolbar(g), - GTK_TOOL_ITEM(item), - gtk_toolbar_get_drop_index( - nsgtk_scaffolding_toolbar(g), x, y)); - return FALSE; -} /** * called when hovering above the store */ -gboolean nsgtk_toolbar_store_action(GtkWidget *widget, GdkDragContext *gdc, +static gboolean +nsgtk_toolbar_store_action(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { return FALSE; } -/** - * called when hovering stops - */ -void nsgtk_toolbar_clear(GtkWidget *widget, GdkDragContext *gdc, guint time, - gpointer data) -{ - gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(widget), NULL, 0); -} /** - * widget factory for creation of toolbar item widgets - * \param g the reference scaffolding - * \param i the id of the widget - * \param theme the theme to make the widgets from + * create store window */ -GtkWidget *nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, - nsgtk_toolbar_button i, struct nsgtk_theme *theme) +static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g) { - GtkWidget *w = NULL; - - switch(i) { - -/* gtk_tool_button_new() accepts NULL args */ -#define MAKE_STOCKBUTTON(p, q) \ - case p##_BUTTON: { \ - GtkStockItem item; \ - if (nsgtk_stock_lookup(q, &item) && \ - (item.label != NULL)) { \ - char *label = NULL; \ - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ - theme->image[p##_BUTTON]), label)); \ - label = remove_underscores(item.label, false); \ - free(label); \ - label = NULL; \ - } else { \ - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ - theme->image[p##_BUTTON]), q)); \ - } \ - break; \ + int x = 0, y = 0; + GError* error = NULL; + struct nsgtk_theme *theme = + nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); + if (theme == NULL) { + warn_user(messages_get("NoMemory"), 0); + nsgtk_toolbar_cancel_clicked(NULL, g); + return; } - MAKE_STOCKBUTTON(HOME, NSGTK_STOCK_HOME) - MAKE_STOCKBUTTON(BACK, NSGTK_STOCK_GO_BACK) - MAKE_STOCKBUTTON(FORWARD, NSGTK_STOCK_GO_FORWARD) - MAKE_STOCKBUTTON(STOP, NSGTK_STOCK_STOP) - MAKE_STOCKBUTTON(RELOAD, NSGTK_STOCK_REFRESH) -#undef MAKE_STOCKBUTTON - - case HISTORY_BUTTON: - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( - theme->image[HISTORY_BUTTON]), "")); - break; - - case URL_BAR_ITEM: { - GtkWidget *entry = nsgtk_entry_new(); - w = GTK_WIDGET(gtk_tool_item_new()); - - if ((entry == NULL) || (w == NULL)) { - warn_user(messages_get("NoMemory"), 0); - return NULL; - } - - nsgtk_entry_set_icon_from_pixbuf(entry, - GTK_ENTRY_ICON_PRIMARY, - favicon_pixbuf); - - gtk_container_add(GTK_CONTAINER(w), entry); - gtk_tool_item_set_expand(GTK_TOOL_ITEM(w), TRUE); - break; + window->glade = gtk_builder_new(); + if (!gtk_builder_add_from_file(window->glade, + glade_file_location->toolbar, + &error)) { + g_warning ("Couldn't load builder file: %s", error->message); + g_error_free (error); + warn_user(messages_get("NoMemory"), 0); + nsgtk_toolbar_cancel_clicked(NULL, g); + free(theme); + return; } - case THROBBER_ITEM: { - if ((nsgtk_throbber == NULL) || - (nsgtk_throbber->framedata == NULL) || - (nsgtk_throbber->framedata[0] == NULL)) { - return NULL; - } - - if (edit_mode) { - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( - gtk_image_new_from_pixbuf( - nsgtk_throbber->framedata[0])), - "[throbber]")); - } else { - GtkWidget *image; + gtk_builder_connect_signals(window->glade, NULL); - w = GTK_WIDGET(gtk_tool_item_new()); + window->window = GTK_WIDGET(gtk_builder_get_object(window->glade, "toolbarwindow")); + if (window->window == NULL) { + warn_user(messages_get("NoMemory"), 0); + nsgtk_toolbar_cancel_clicked(NULL, g); + free(theme); + return; + } - image = gtk_image_new_from_pixbuf(nsgtk_throbber->framedata[0]); - if (image != NULL) { - nsgtk_widget_set_alignment(image, - GTK_ALIGN_CENTER, - GTK_ALIGN_CENTER); - nsgtk_widget_set_margins(image, 3, 0); + window->widgetvbox = GTK_WIDGET(gtk_builder_get_object(window->glade, "widgetvbox")); + if (window->widgetvbox == NULL) { + warn_user(messages_get("NoMemory"), 0); + nsgtk_toolbar_cancel_clicked(NULL, g); + free(theme); + return; + } - gtk_container_add(GTK_CONTAINER(w), image); - } + window->numberh = NSGTK_STORE_WIDTH; /* preset to width [in buttons] of */ + /* store to cause creation of a new toolbar */ + window->currentbutton = -1; + /* load toolbuttons */ + /* add toolbuttons to window */ + /* set event handlers */ + for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + if (i == URL_BAR_ITEM) + continue; + window->store_buttons[i] = + nsgtk_toolbar_make_widget(g, i, theme); + if (window->store_buttons[i] == NULL) { + warn_user(messages_get("NoMemory"), 0); + continue; } - break; + nsgtk_toolbar_add_store_widget(window->store_buttons[i]); + g_signal_connect(window->store_buttons[i], "drag-data-get", + G_CALLBACK( + nsgtk_scaffolding_button(g, i)->dataplus), g); } + free(theme); + gtk_window_set_transient_for(GTK_WINDOW(window->window), + nsgtk_scaffolding_window(g)); + gtk_window_set_title(GTK_WINDOW(window->window), messages_get( + "gtkToolBarTitle")); + gtk_window_set_accept_focus(GTK_WINDOW(window->window), FALSE); + gtk_drag_dest_set(GTK_WIDGET(window->window), GTK_DEST_DEFAULT_MOTION | + GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY); + gtk_widget_show_all(window->window); + gtk_window_set_position(GTK_WINDOW(window->window), + GTK_WIN_POS_CENTER_ON_PARENT); + gtk_window_get_position(nsgtk_scaffolding_window(g), &x, &y); + gtk_window_move(GTK_WINDOW(window->window), x, y + 100); + g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->glade, "cancelbutton")), + "clicked", + G_CALLBACK(nsgtk_toolbar_cancel_clicked), + g); - case WEBSEARCH_ITEM: { - if (edit_mode) - return GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( - nsgtk_image_new_from_stock(NSGTK_STOCK_FIND, - GTK_ICON_SIZE_LARGE_TOOLBAR)), - "[websearch]")); + g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->glade, "okbutton")), + "clicked", G_CALLBACK(nsgtk_toolbar_persist), g); + g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->glade, "resetbutton")), + "clicked", G_CALLBACK(nsgtk_toolbar_reset), g); + g_signal_connect(window->window, "delete-event", + G_CALLBACK(nsgtk_toolbar_delete), g); + g_signal_connect(window->window, "drag-drop", + G_CALLBACK(nsgtk_toolbar_store_return), g); + g_signal_connect(window->window, "drag-motion", + G_CALLBACK(nsgtk_toolbar_store_action), g); +} - GtkWidget *entry = nsgtk_entry_new(); +/** + * change behaviour of scaffoldings while editing toolbar + * + * All buttons as well as window clicks are desensitized; then buttons + * in the front window are changed to movable buttons + */ +void nsgtk_toolbar_customization_init(struct nsgtk_scaffolding *g) +{ + int i; + struct nsgtk_scaffolding *list; + edit_mode = true; - w = GTK_WIDGET(gtk_tool_item_new()); + list = nsgtk_scaffolding_iterate(NULL); + while (list) { + g_signal_handler_block(GTK_WIDGET( + nsgtk_window_get_layout( + nsgtk_scaffolding_top_level(list))), + nsgtk_window_get_signalhandler( + nsgtk_scaffolding_top_level(list), + NSGTK_WINDOW_SIGNAL_CLICK)); + g_signal_handler_block(GTK_WIDGET( + nsgtk_window_get_layout( + nsgtk_scaffolding_top_level(list))), + nsgtk_window_get_signalhandler( + nsgtk_scaffolding_top_level(list), + NSGTK_WINDOW_SIGNAL_REDRAW)); + nsgtk_widget_override_background_color( + GTK_WIDGET(nsgtk_window_get_layout( + nsgtk_scaffolding_top_level(list))), + GTK_STATE_NORMAL, 0, 0xEEEE, 0xEEEE, 0xEEEE); - if ((entry == NULL) || (w == NULL)) { - warn_user(messages_get("NoMemory"), 0); - return NULL; + if (list == g) { + list = nsgtk_scaffolding_iterate(list); + continue; } - - gtk_widget_set_size_request(entry, NSGTK_WEBSEARCH_WIDTH, -1); - - nsgtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, - NSGTK_STOCK_INFO); - - gtk_container_add(GTK_CONTAINER(w), entry); - break; + /* set sensitive for all gui_windows save g */ + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_window( + list)), FALSE); + list = nsgtk_scaffolding_iterate(list); } + /* set sensitive for all of g save toolbar */ + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_menu_bar(g)), + FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_notebook(g)), + FALSE); -/* gtk_tool_button_new accepts NULL args */ -#define MAKE_MENUBUTTON(p, q) \ - case p##_BUTTON: { \ - char *label = NULL; \ - label = remove_underscores(messages_get(#q), false); \ - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ - theme->image[p##_BUTTON]), label)); \ - if (label != NULL) \ - free(label); \ - break; \ + /* set editable aspect for toolbar */ + gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), + nsgtk_toolbar_clear_toolbar, g); + nsgtk_toolbar_set_physical(g); + /* memorize button locations, set editable */ + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + window->buttonlocations[i] = nsgtk_scaffolding_button(g, i) + ->location; + if ((window->buttonlocations[i] == -1) || (i == URL_BAR_ITEM)) + continue; + gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( + nsgtk_scaffolding_button(g, i)->button), TRUE); + gtk_drag_source_set(GTK_WIDGET(nsgtk_scaffolding_button( + g, i)->button), GDK_BUTTON1_MASK, &entry, 1, + GDK_ACTION_COPY); + nsgtk_toolbar_temp_connect(g, i); } - MAKE_MENUBUTTON(NEWWINDOW, gtkNewWindow) - MAKE_MENUBUTTON(NEWTAB, gtkNewTab) - MAKE_MENUBUTTON(OPENFILE, gtkOpenFile) - MAKE_MENUBUTTON(CLOSETAB, gtkCloseTab) - MAKE_MENUBUTTON(CLOSEWINDOW, gtkCloseWindow) - MAKE_MENUBUTTON(SAVEPAGE, gtkSavePage) - MAKE_MENUBUTTON(PRINTPREVIEW, gtkPrintPreview) - MAKE_MENUBUTTON(PRINT, gtkPrint) - MAKE_MENUBUTTON(QUIT, gtkQuitMenu) - MAKE_MENUBUTTON(CUT, gtkCut) - MAKE_MENUBUTTON(COPY, gtkCopy) - MAKE_MENUBUTTON(PASTE, gtkPaste) - MAKE_MENUBUTTON(DELETE, gtkDelete) - MAKE_MENUBUTTON(SELECTALL, gtkSelectAll) - MAKE_MENUBUTTON(PREFERENCES, gtkPreferences) - MAKE_MENUBUTTON(ZOOMPLUS, gtkZoomPlus) - MAKE_MENUBUTTON(ZOOMMINUS, gtkZoomMinus) - MAKE_MENUBUTTON(ZOOMNORMAL, gtkZoomNormal) - MAKE_MENUBUTTON(FULLSCREEN, gtkFullScreen) - MAKE_MENUBUTTON(VIEWSOURCE, gtkViewSource) - MAKE_MENUBUTTON(CONTENTS, gtkContents) - MAKE_MENUBUTTON(ABOUT, gtkAbout) - MAKE_MENUBUTTON(PDF, gtkPDF) - MAKE_MENUBUTTON(PLAINTEXT, gtkPlainText) - MAKE_MENUBUTTON(DRAWFILE, gtkDrawFile) - MAKE_MENUBUTTON(POSTSCRIPT, gtkPostScript) - MAKE_MENUBUTTON(FIND, gtkFind) - MAKE_MENUBUTTON(DOWNLOADS, gtkDownloads) - MAKE_MENUBUTTON(SAVEWINDOWSIZE, gtkSaveWindowSize) - MAKE_MENUBUTTON(TOGGLEDEBUGGING, gtkToggleDebugging) - MAKE_MENUBUTTON(SAVEBOXTREE, gtkDebugBoxTree) - MAKE_MENUBUTTON(SAVEDOMTREE, gtkDebugDomTree) - MAKE_MENUBUTTON(LOCALHISTORY, gtkLocalHistory) - MAKE_MENUBUTTON(GLOBALHISTORY, gtkGlobalHistory) - MAKE_MENUBUTTON(ADDBOOKMARKS, gtkAddBookMarks) - MAKE_MENUBUTTON(SHOWBOOKMARKS, gtkShowBookMarks) - MAKE_MENUBUTTON(SHOWCOOKIES, gtkShowCookies) - MAKE_MENUBUTTON(OPENLOCATION, gtkOpenLocation) - MAKE_MENUBUTTON(NEXTTAB, gtkNextTab) - MAKE_MENUBUTTON(PREVTAB, gtkPrevTab) - MAKE_MENUBUTTON(GUIDE, gtkGuide) - MAKE_MENUBUTTON(INFO, gtkUserInformation) -#undef MAKE_MENUBUTTON + /* add move button listeners */ + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), + "drag-drop", G_CALLBACK(nsgtk_toolbar_data), g); + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), + "drag-data-received", G_CALLBACK( + nsgtk_toolbar_move_complete), g); + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), + "drag-motion", G_CALLBACK(nsgtk_toolbar_action), g); + g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), + "drag-leave", G_CALLBACK( + nsgtk_toolbar_clear), g); - default: - break; + /* set data types */ + gtk_drag_dest_set(GTK_WIDGET(nsgtk_scaffolding_toolbar(g)), + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, + &entry, 1, GDK_ACTION_COPY); + /* open toolbar window */ + nsgtk_toolbar_window_open(g); +} + +/** + * set toolbar logical -> physical; physically visible toolbar buttons are made + * to correspond to the logically stored schema in terms of location + * visibility etc + */ +void nsgtk_toolbar_set_physical(struct nsgtk_scaffolding *g) +{ + int i; + struct nsgtk_theme *theme = + nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); + if (theme == NULL) { + warn_user(messages_get("NoMemory"), 0); + return; } - return w; + /* simplest is to clear the toolbar then reload it from memory */ + gtk_container_foreach(GTK_CONTAINER(nsgtk_scaffolding_toolbar(g)), + nsgtk_toolbar_clear_toolbar, g); + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) + nsgtk_toolbar_add_item_to_toolbar(g, i, theme); + gtk_widget_show_all(GTK_WIDGET(nsgtk_scaffolding_toolbar(g))); + free(theme); } /** * \return toolbar item id when a widget is an element of the scaffolding * else -1 */ -int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, struct nsgtk_scaffolding *g) +int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, + struct nsgtk_scaffolding *g) { int i; for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { @@ -870,47 +942,13 @@ int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, struct nsgtk_scaffolding return -1; } -/** - * \return toolbar item id from location when there is an item at that logical - * location; else -1 - */ -nsgtk_toolbar_button -nsgtk_toolbar_get_id_at_location(struct nsgtk_scaffolding *g, int i) -{ - int q; - for (q = BACK_BUTTON; q < PLACEHOLDER_BUTTON; q++) - if (nsgtk_scaffolding_button(g, q)->location == i) - return q; - return -1; -} - -/** - * connect 'normal' handlers to toolbar buttons - */ - -void nsgtk_toolbar_connect_all(struct nsgtk_scaffolding *g) -{ - int q, i; - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - q = nsgtk_toolbar_get_id_at_location(g, i); - if (q == -1) - continue; - if (nsgtk_scaffolding_button(g, q)->button != NULL) - g_signal_connect( - nsgtk_scaffolding_button(g, q)->button, - "size-allocate", G_CALLBACK( - nsgtk_scaffolding_toolbar_size_allocate - ), g); - nsgtk_toolbar_set_handler(g, q); - } -} /** * add handlers to factory widgets * \param g the scaffolding to attach handlers to * \param i the toolbar item id */ -void +static void nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) { switch(i){ @@ -947,6 +985,27 @@ nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) } } +/** + * connect 'normal' handlers to toolbar buttons + */ +void nsgtk_toolbar_connect_all(struct nsgtk_scaffolding *g) +{ + int q, i; + for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { + q = nsgtk_toolbar_get_id_at_location(g, i); + if (q == -1) + continue; + if (nsgtk_scaffolding_button(g, q)->button != NULL) + g_signal_connect( + nsgtk_scaffolding_button(g, q)->button, + "size-allocate", G_CALLBACK( + nsgtk_scaffolding_toolbar_size_allocate + ), g); + nsgtk_toolbar_set_handler(g, q); + } +} + + #define DATAHANDLER(p, q, r)\ gboolean nsgtk_toolbar_##p##_button_data(GtkWidget *widget, GdkDragContext\ *cont, GtkSelectionData *selection, guint info, guint time,\ @@ -1036,19 +1095,6 @@ DATAHANDLER(throbber, THROBBER, window) DATAHANDLER(websearch, WEBSEARCH, window) #undef DATAHANDLER -/** - * connect temporary handler for toolbar edit events - */ -void nsgtk_toolbar_temp_connect(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) -{ - if ((i == URL_BAR_ITEM) || - (nsgtk_scaffolding_button(g, i)->button == NULL) || - (nsgtk_scaffolding_button(g, i)->dataminus == NULL)) - return; - g_signal_connect(nsgtk_scaffolding_button(g, i)->button, - "drag-data-get", G_CALLBACK(nsgtk_scaffolding_button( - g, i)->dataminus), g); -} /** * load toolbar settings from file; file is a set of fields arranged as @@ -1090,49 +1136,3 @@ void nsgtk_toolbar_customization_load(struct nsgtk_scaffolding *g) buffer1 = strtok_r(NULL, "|", &ptr); } } - -/** - * cast toolbar settings to all scaffoldings referenced from the global linked - * list of gui_windows - */ -void nsgtk_toolbar_cast(struct nsgtk_scaffolding *g) -{ - int i; - struct nsgtk_scaffolding *list; - - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - window->buttonlocations[i] = - ((nsgtk_scaffolding_button(g, i)->location - >= -1) && - (nsgtk_scaffolding_button(g, i)->location - < PLACEHOLDER_BUTTON)) ? - nsgtk_scaffolding_button(g, i)->location : -1; - } - - list = nsgtk_scaffolding_iterate(NULL); - while (list) { - if (list != g) - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) - nsgtk_scaffolding_button(list, i)->location = - window->buttonlocations[i]; - list = nsgtk_scaffolding_iterate(list); - } -} - -/** - * save toolbar settings to file - */ -void nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g) -{ - int i; - FILE *f = fopen(toolbar_indices_file_location, "w"); - if (f == NULL){ - warn_user("gtkFileError", toolbar_indices_file_location); - return; - } - for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { - fprintf(f, "%d;%d|", i, nsgtk_scaffolding_button(g, i)->location); - } - fclose(f); -} - -- cgit v1.2.3