/** * called when a widget is dropped onto the store window */ gboolean nsgtk_toolbar_store_return(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; int q, i; if ((window->fromstore) || (window->currentbutton == -1)) { window->currentbutton = -1; return FALSE; } if (nsgtk_scaffolding_button(g, window->currentbutton)->location != -1) { /* 'move' all widgets further right, 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--; } gtk_container_remove(GTK_CONTAINER( nsgtk_scaffolding_toolbar(g)), GTK_WIDGET( nsgtk_scaffolding_button(g, window->currentbutton)->button)); nsgtk_scaffolding_button(g, window->currentbutton)->location = -1; } window->currentbutton = -1; gtk_drag_finish(gdc, TRUE, TRUE, time); return FALSE; }
/** * add handlers to factory widgets * \param g the scaffolding to attach handlers to * \param i the toolbar item id */ void nsgtk_toolbar_set_handler(nsgtk_scaffolding *g, nsgtk_toolbar_button i) { switch(i){ case URL_BAR_ITEM: nsgtk_scaffolding_update_url_bar_ref(g); g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)), "activate", G_CALLBACK( nsgtk_window_url_activate_event), g); g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)), "changed", G_CALLBACK( nsgtk_window_url_changed), g); break; case THROBBER_ITEM: nsgtk_scaffolding_update_throbber_ref(g); break; case WEBSEARCH_ITEM: nsgtk_scaffolding_update_websearch_ref(g); g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_websearch(g)), "activate", G_CALLBACK( nsgtk_websearch_activate), g); g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_websearch(g)), "button-press-event", G_CALLBACK( nsgtk_websearch_clear), g); break; default: if ((nsgtk_scaffolding_button(g, i)->bhandler != NULL) && (nsgtk_scaffolding_button(g, i)->button != NULL)) g_signal_connect(nsgtk_scaffolding_button(g, i)-> button, "clicked", G_CALLBACK(nsgtk_scaffolding_button(g, i)->bhandler), g); break; } }
/** * connect temporary handler for toolbar edit events */ void nsgtk_toolbar_temp_connect(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); }
/** * \return toolbar item id when a widget is an element of the scaffolding * else -1 */ int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, nsgtk_scaffolding *g) { int i; for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { if ((nsgtk_scaffolding_button(g, i)->location != -1) && (widget == GTK_WIDGET( nsgtk_scaffolding_button(g, i)->button))) { return i; } } return -1; }
/** * add item to toolbar * \param g the scaffolding whose toolbar an item is added to * \param i the location in the toolbar * the function should be called, when multiple items are being added, * in ascending order */ void nsgtk_toolbar_add_item_to_toolbar(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; } }
void nsgtk_toolbar_connect_all(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); } }
/** * \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(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; }
/** * cast toolbar settings to all scaffoldings referenced from the global linked * list of gui_windows */ void nsgtk_toolbar_cast(nsgtk_scaffolding *g) { int i; nsgtk_scaffolding *list = scaf_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; 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 'reload defaults' button is clicked */ gboolean nsgtk_toolbar_reset(GtkWidget *widget, gpointer data) { nsgtk_scaffolding *g = (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; }
/** * save toolbar settings to file */ void nsgtk_toolbar_customization_save(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); }
/** * load toolbar settings from file; file is a set of fields arranged as * [itemreference];[itemlocation]|[itemreference];[itemlocation]| etc */ void nsgtk_toolbar_customization_load(nsgtk_scaffolding *g) { int i, ii; char *val; char buffer[SLEN("11;|") * 2 * PLACEHOLDER_BUTTON]; /* numbers 0-99 */ buffer[0] = '\0'; char *buffer1, *subbuffer, *ptr = NULL, *pter = NULL; for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) nsgtk_scaffolding_button(g, i)->location = (i <= THROBBER_ITEM) ? i : -1; FILE *f = fopen(toolbar_indices_file_location, "r"); if (f == NULL) { warn_user(messages_get("gtkFileError"), toolbar_indices_file_location); return; } val = fgets(buffer, sizeof buffer, f); if (val == NULL) { LOG(("empty read toolbar settings")); } fclose(f); i = BACK_BUTTON; ii = BACK_BUTTON; buffer1 = strtok_r(buffer, "|", &ptr); while (buffer1 != NULL) { subbuffer = strtok_r(buffer1, ";", &pter); i = atoi(subbuffer); subbuffer = strtok_r(NULL, ";", &pter); ii = atoi(subbuffer); if ((i >= BACK_BUTTON) && (i < PLACEHOLDER_BUTTON) && (ii >= -1) && (ii < PLACEHOLDER_BUTTON)) { nsgtk_scaffolding_button(g, i)->location = ii; } buffer1 = strtok_r(NULL, "|", &ptr); } }
/** * when cancel button is clicked */ gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data) { edit_mode = false; nsgtk_scaffolding *g = (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; }
void nsgtk_theme_implement(struct gtk_scaffolding *g) { struct nsgtk_theme *theme[IMAGE_SET_COUNT]; int i; struct nsgtk_button_connect *button; struct gtk_search *search; for (i = 0; i <= IMAGE_SET_POPUP_MENU; i++) theme[i] = nsgtk_theme_load(GTK_ICON_SIZE_MENU); theme[IMAGE_SET_BUTTONS] = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) { if ((i == URL_BAR_ITEM) || (i == THROBBER_ITEM) || (i == WEBSEARCH_ITEM)) continue; button = nsgtk_scaffolding_button(g, i); if (button == NULL) continue; /* gtk_image_menu_item_set_image accepts NULL image */ if ((button->main != NULL) && (theme[IMAGE_SET_MAIN_MENU] != NULL)) { gtk_image_menu_item_set_image(button->main, GTK_WIDGET( theme[IMAGE_SET_MAIN_MENU]-> image[i])); gtk_widget_show_all(GTK_WIDGET(button->main)); } if ((button->rclick != NULL) && (theme[IMAGE_SET_RCLICK_MENU] != NULL)) { gtk_image_menu_item_set_image(button->rclick, GTK_WIDGET( theme[IMAGE_SET_RCLICK_MENU]-> image[i])); gtk_widget_show_all(GTK_WIDGET(button->rclick)); } if ((button->popup != NULL) && (theme[IMAGE_SET_POPUP_MENU] != NULL)) { gtk_image_menu_item_set_image(button->popup, GTK_WIDGET( theme[IMAGE_SET_POPUP_MENU]-> image[i])); gtk_widget_show_all(GTK_WIDGET(button->popup)); } if ((button->location != -1) && (button->button != NULL) && (theme[IMAGE_SET_BUTTONS] != NULL)) { gtk_tool_button_set_icon_widget( GTK_TOOL_BUTTON(button->button), GTK_WIDGET( theme[IMAGE_SET_BUTTONS]-> image[i])); gtk_widget_show_all(GTK_WIDGET(button->button)); } } /* set search bar images */ search = nsgtk_scaffolding_search(g); if ((search != NULL) && (theme[IMAGE_SET_MAIN_MENU] != NULL)) { /* gtk_tool_button_set_icon_widget accepts NULL image */ if (search->buttons[SEARCH_BACK_BUTTON] != NULL) { gtk_tool_button_set_icon_widget( search->buttons[SEARCH_BACK_BUTTON], GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]-> searchimage[SEARCH_BACK_BUTTON])); gtk_widget_show_all(GTK_WIDGET( search->buttons[SEARCH_BACK_BUTTON])); } if (search->buttons[SEARCH_FORWARD_BUTTON] != NULL) { gtk_tool_button_set_icon_widget( search->buttons[SEARCH_FORWARD_BUTTON], GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]-> searchimage[SEARCH_FORWARD_BUTTON])); gtk_widget_show_all(GTK_WIDGET( search->buttons[ SEARCH_FORWARD_BUTTON])); } if (search->buttons[SEARCH_CLOSE_BUTTON] != NULL) { gtk_tool_button_set_icon_widget( search->buttons[SEARCH_CLOSE_BUTTON], GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]-> searchimage[SEARCH_CLOSE_BUTTON])); gtk_widget_show_all(GTK_WIDGET( search->buttons[SEARCH_CLOSE_BUTTON])); } } for (i = 0; i < IMAGE_SET_COUNT; i++) { if (theme[i] != NULL) { free(theme[i]); } } }
/** * called when a widget is dropped onto the toolbar */ gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { nsgtk_scaffolding *g = (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; } /* 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 */ gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), nsgtk_scaffolding_button(g, window->currentbutton)->button, ind); gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( nsgtk_scaffolding_button(g, window->currentbutton)->button), TRUE); gtk_drag_source_set(GTK_WIDGET( nsgtk_scaffolding_button(g, window->currentbutton)->button), GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_COPY); nsgtk_toolbar_temp_connect(g, window->currentbutton); gtk_widget_show_all(GTK_WIDGET( nsgtk_scaffolding_button(g, window->currentbutton)->button)); window->currentbutton = -1; return TRUE; }
/** * create store window */ void nsgtk_toolbar_window_open(nsgtk_scaffolding *g) { 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; } 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); return; } 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; } 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; } 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; } 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); 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); }
/** * 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(nsgtk_scaffolding *g) { int i; nsgtk_scaffolding *list = scaf_list; edit_mode = true; 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; } /* 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); } /* 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); }