diff options
author | Vincent Sanders <vince@kyllikki.org> | 2015-04-12 01:12:43 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2015-04-12 01:12:43 +0100 |
commit | 997e8999d5a3a496a81d45b37f723d5bc539f5c4 (patch) | |
tree | 9917f68ec795c642abe11e9f6f6d4982cf458ede /gtk/toolbar.c | |
parent | f3158f79b6357558e3a0083039857bba21c6ca5b (diff) | |
download | netsurf-997e8999d5a3a496a81d45b37f723d5bc539f5c4.tar.gz netsurf-997e8999d5a3a496a81d45b37f723d5bc539f5c4.tar.bz2 |
Refactor GTK toolbar handling to correctly cope with text labels
Diffstat (limited to 'gtk/toolbar.c')
-rw-r--r-- | gtk/toolbar.c | 1282 |
1 files changed, 641 insertions, 641 deletions
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); -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); +/** + * 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); +} /** - * change behaviour of scaffoldings while editing toolbar + * connect temporary handler for toolbar edit events * - * All buttons as well as window clicks are desensitized; then buttons - * in the front window are changed to movable buttons + * \param g The scaffolding + * \param bi The button index */ -void nsgtk_toolbar_customization_init(struct nsgtk_scaffolding *g) +static void nsgtk_toolbar_temp_connect(struct nsgtk_scaffolding *g, + nsgtk_toolbar_button bi) { - int i; - struct nsgtk_scaffolding *list; - edit_mode = true; - - 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 (list == g) { - list = nsgtk_scaffolding_iterate(list); - continue; + 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); } - /* 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); +} - /* 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); +/** + * get scaffolding button index of button at location + * + * \return toolbar item id from location when there is an item at that logical + * location; else -1 + */ +static 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; + } } - - /* 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); - - /* 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); + return -1; } /** - * create store window + * 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 */ -void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g) +static GtkWidget * +nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, + nsgtk_toolbar_button i, + struct nsgtk_theme *theme) { - 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; - } + GtkWidget *w = NULL; - 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; + 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; \ } - gtk_builder_connect_signals(window->glade, NULL); + 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 - 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; + 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; + } + + 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->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; + 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; } - 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) { + 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]")); + + GtkWidget *entry = nsgtk_entry_new(); + + w = GTK_WIDGET(gtk_tool_item_new()); + + if ((entry == NULL) || (w == NULL)) { warn_user(messages_get("NoMemory"), 0); - continue; + return NULL; } - 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); + + 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; } - 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); - 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_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; } /** - * when titlebar / alt-F4 window close event happens + * called when a widget is dropped onto the toolbar */ -gboolean nsgtk_toolbar_delete(GtkWidget *widget, GdkEvent *event, - gpointer data) +static gboolean +nsgtk_toolbar_data(GtkWidget *widget, + GdkDragContext *gdc, + gint x, + gint y, + 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]; + 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; } - nsgtk_toolbar_set_physical(g); - nsgtk_toolbar_connect_all(g); - nsgtk_toolbar_close(g); - nsgtk_scaffolding_set_sensitivity(g); - gtk_widget_destroy(window->window); + 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; + } + /* 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++; + } + 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); + + 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; + 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) { + 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; + } -/* 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; \ + 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; } - 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 + gtk_builder_connect_signals(window->glade, NULL); - case HISTORY_BUTTON: - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( - theme->image[HISTORY_BUTTON]), "")); - break; + 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; + } - case URL_BAR_ITEM: { - GtkWidget *entry = nsgtk_entry_new(); - w = GTK_WIDGET(gtk_tool_item_new()); + 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; + } - if ((entry == NULL) || (w == NULL)) { + 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); - return NULL; + continue; } - - 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; + 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 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; + 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); +} - w = GTK_WIDGET(gtk_tool_item_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; - 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); + 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); - gtk_container_add(GTK_CONTAINER(w), image); - } + if (list == g) { + list = nsgtk_scaffolding_iterate(list); + continue; } - 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); - 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]")); - - 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; - } - - 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 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); } -/* 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; \ - } + /* 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); - 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 + /* 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); - default: - break; + /* 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); -} - |