diff options
Diffstat (limited to 'src/gui_gtk.c')
-rw-r--r-- | src/gui_gtk.c | 1239 |
1 files changed, 11 insertions, 1228 deletions
diff --git a/src/gui_gtk.c b/src/gui_gtk.c index 6a657a3ee8..52d75e4a22 100644 --- a/src/gui_gtk.c +++ b/src/gui_gtk.c @@ -62,53 +62,6 @@ # include <gnome.h> #endif -#if defined(FEAT_GUI_DIALOG) && !defined(HAVE_GTK2) -# include "../pixmaps/alert.xpm" -# include "../pixmaps/error.xpm" -# include "../pixmaps/generic.xpm" -# include "../pixmaps/info.xpm" -# include "../pixmaps/quest.xpm" -#endif - -#if defined(FEAT_TOOLBAR) && !defined(HAVE_GTK2) -/* - * Icons used by the toolbar code. - */ -#include "../pixmaps/tb_new.xpm" -#include "../pixmaps/tb_open.xpm" -#include "../pixmaps/tb_close.xpm" -#include "../pixmaps/tb_save.xpm" -#include "../pixmaps/tb_print.xpm" -#include "../pixmaps/tb_cut.xpm" -#include "../pixmaps/tb_copy.xpm" -#include "../pixmaps/tb_paste.xpm" -#include "../pixmaps/tb_find.xpm" -#include "../pixmaps/tb_find_next.xpm" -#include "../pixmaps/tb_find_prev.xpm" -#include "../pixmaps/tb_find_help.xpm" -#include "../pixmaps/tb_exit.xpm" -#include "../pixmaps/tb_undo.xpm" -#include "../pixmaps/tb_redo.xpm" -#include "../pixmaps/tb_help.xpm" -#include "../pixmaps/tb_macro.xpm" -#include "../pixmaps/tb_make.xpm" -#include "../pixmaps/tb_save_all.xpm" -#include "../pixmaps/tb_jump.xpm" -#include "../pixmaps/tb_ctags.xpm" -#include "../pixmaps/tb_load_session.xpm" -#include "../pixmaps/tb_save_session.xpm" -#include "../pixmaps/tb_new_session.xpm" -#include "../pixmaps/tb_blank.xpm" -#include "../pixmaps/tb_maximize.xpm" -#include "../pixmaps/tb_split.xpm" -#include "../pixmaps/tb_minimize.xpm" -#include "../pixmaps/tb_shell.xpm" -#include "../pixmaps/tb_replace.xpm" -#include "../pixmaps/tb_vsplit.xpm" -#include "../pixmaps/tb_maxwidth.xpm" -#include "../pixmaps/tb_minwidth.xpm" -#endif /* FEAT_TOOLBAR && !HAVE_GTK2 */ - #ifdef FEAT_GUI_GTK # include <gdk/gdkkeysyms.h> # include <gdk/gdk.h> @@ -137,11 +90,8 @@ typedef int GtkWidget; static void entry_activate_cb(GtkWidget *widget, gpointer data); static void entry_changed_cb(GtkWidget *entry, GtkWidget *dialog); static void find_replace_cb(GtkWidget *widget, gpointer data); -#ifndef HAVE_GTK2 -static void gui_gtk_position_in_parent(GtkWidget *parent, GtkWidget *child, gui_win_pos_T where); -#endif -#if defined(FEAT_TOOLBAR) && defined(HAVE_GTK2) +#if defined(FEAT_TOOLBAR) /* * Table from BuiltIn## icon indices to GTK+ stock IDs. Order must exactly * match toolbar_names[] in menu.c! All stock icons including the "vim-*" @@ -298,9 +248,9 @@ toolbar_button_focus_in_event(GtkWidget *widget UNUSED, return TRUE; } -#endif /* FEAT_TOOLBAR && HAVE_GTK2 */ +#endif /* FEAT_TOOLBAR */ -#if (defined(FEAT_TOOLBAR) && defined(HAVE_GTK2)) || defined(PROTO) +#if defined(FEAT_TOOLBAR) || defined(PROTO) void gui_gtk_register_stock_icons(void) @@ -330,19 +280,8 @@ gui_gtk_register_stock_icons(void) g_object_unref(factory); } -#endif /* FEAT_TOOLBAR && HAVE_GTK2 */ - +#endif /* FEAT_TOOLBAR */ -/* - * Only use accelerators when gtk_menu_ensure_uline_accel_group() is - * available, which is in version 1.2.1. That was the first version where - * accelerators properly worked (according to the change log). - */ -#ifdef GTK_CHECK_VERSION -# if GTK_CHECK_VERSION(1, 2, 1) -# define GTK_USE_ACCEL -# endif -#endif #if defined(FEAT_MENU) || defined(PROTO) @@ -364,9 +303,7 @@ translate_mnemonic_tag(char_u *name, int use_mnemonic) char_u *pdest; int n_underscores = 0; -# ifdef HAVE_GTK2 name = CONVERT_TO_UTF8(name); -# endif if (name == NULL) return NULL; @@ -401,14 +338,10 @@ translate_mnemonic_tag(char_u *name, int use_mnemonic) *pdest = NUL; } -# ifdef HAVE_GTK2 CONVERT_TO_UTF8_FREE(name); -# endif return buf; } -# ifdef HAVE_GTK2 - static void menu_item_new(vimmenu_T *menu, GtkWidget *parent_widget) { @@ -445,96 +378,6 @@ menu_item_new(vimmenu_T *menu, GtkWidget *parent_widget) gtk_widget_show_all(menu->id); } -# else /* !HAVE_GTK2 */ - -/* - * Create a highly customized menu item by hand instead of by using: - * - * gtk_menu_item_new_with_label(menu->dname); - * - * This is necessary, since there is no other way in GTK+ 1 to get the - * not automatically parsed accelerator stuff right. - */ - static void -menu_item_new(vimmenu_T *menu, GtkWidget *parent_widget) -{ - GtkWidget *widget; - GtkWidget *bin; - GtkWidget *label; - char_u *name; - guint accel_key; - - widget = gtk_widget_new(GTK_TYPE_MENU_ITEM, - "GtkWidget::visible", TRUE, - "GtkWidget::sensitive", TRUE, - /* "GtkWidget::parent", parent->submenu_id, */ - NULL); - bin = gtk_widget_new(GTK_TYPE_HBOX, - "GtkWidget::visible", TRUE, - "GtkWidget::parent", widget, - "GtkBox::spacing", 16, - NULL); - label = gtk_widget_new(GTK_TYPE_ACCEL_LABEL, - "GtkWidget::visible", TRUE, - "GtkWidget::parent", bin, - "GtkAccelLabel::accel_widget", widget, - "GtkMisc::xalign", 0.0, - NULL); - menu->label = label; - - if (menu->actext) - gtk_widget_new(GTK_TYPE_LABEL, - "GtkWidget::visible", TRUE, - "GtkWidget::parent", bin, - "GtkLabel::label", menu->actext, - "GtkMisc::xalign", 1.0, - NULL); - - /* - * Translate VIM accelerator tagging into GTK+'s. Note that since GTK uses - * underscores as the accelerator key, we need to add an additional under- - * score for each understore that appears in the menu name. - */ -# ifdef GTK_USE_ACCEL - name = translate_mnemonic_tag(menu->name, - (p_wak[0] != 'n' || !GTK_IS_MENU_BAR(parent_widget))); -# else - name = translate_mnemonic_tag(menu->name, FALSE); -# endif - - /* let GTK do its thing */ - accel_key = gtk_label_parse_uline(GTK_LABEL(label), (const char *)name); - vim_free(name); - -# ifdef GTK_USE_ACCEL - /* Don't add accelator if 'winaltkeys' is "no". */ - if (accel_key != GDK_VoidSymbol) - { - if (GTK_IS_MENU_BAR(parent_widget)) - { - if (*p_wak != 'n') - gtk_widget_add_accelerator(widget, - "activate_item", - gui.accel_group, - accel_key, GDK_MOD1_MASK, - (GtkAccelFlags)0); - } - else - { - gtk_widget_add_accelerator(widget, - "activate_item", - gtk_menu_ensure_uline_accel_group(GTK_MENU(parent_widget)), - accel_key, 0, - (GtkAccelFlags)0); - } - } -# endif /* GTK_USE_ACCEL */ - - menu->id = widget; -} - -# endif /* !HAVE_GTK2 */ - void gui_mch_add_menu(vimmenu_T *menu, int idx) { @@ -562,18 +405,6 @@ gui_mch_add_menu(vimmenu_T *menu, int idx) gtk_menu_shell_insert(GTK_MENU_SHELL(parent_widget), menu->id, idx); -#ifndef HAVE_GTK2 - /* - * The "Help" menu is a special case, and should be placed at the far - * right hand side of the menu-bar. It's detected by its high priority. - * - * Right-aligning "Help" is considered bad UI design nowadays. - * Thus lets disable this for GTK+ 2 to match the environment. - */ - if (parent == NULL && menu->priority >= 9999) - gtk_menu_item_right_justify(GTK_MENU_ITEM(menu->id)); -#endif - menu->submenu_id = gtk_menu_new(); gtk_menu_set_accel_group(GTK_MENU(menu->submenu_id), gui.accel_group); @@ -590,117 +421,11 @@ menu_item_activate(GtkWidget *widget UNUSED, gpointer data) { gui_menu_cb((vimmenu_T *)data); -# ifndef HAVE_GTK2 - /* Work around a bug in GTK+ 1: we don't seem to get a focus-in - * event after clicking a menu item shown via :popup. */ - if (!gui.in_focus) - gui_focus_change(TRUE); -# endif - /* make sure the menu action is taken immediately */ if (gtk_main_level() > 0) gtk_main_quit(); } -# if defined(FEAT_TOOLBAR) && !defined(HAVE_GTK2) -/* - * These are the pixmaps used for the default buttons. - * Order must exactly match toolbar_names[] in menu.c! - */ -static char **(built_in_pixmaps[]) = -{ - tb_new_xpm, - tb_open_xpm, - tb_save_xpm, - tb_undo_xpm, - tb_redo_xpm, - tb_cut_xpm, - tb_copy_xpm, - tb_paste_xpm, - tb_print_xpm, - tb_help_xpm, - tb_find_xpm, - tb_save_all_xpm, - tb_save_session_xpm, - tb_new_session_xpm, - tb_load_session_xpm, - tb_macro_xpm, - tb_replace_xpm, - tb_close_xpm, - tb_maximize_xpm, - tb_minimize_xpm, - tb_split_xpm, - tb_shell_xpm, - tb_find_prev_xpm, - tb_find_next_xpm, - tb_find_help_xpm, - tb_make_xpm, - tb_jump_xpm, - tb_ctags_xpm, - tb_vsplit_xpm, - tb_maxwidth_xpm, - tb_minwidth_xpm, - tb_exit_xpm -}; - -/* - * creates a blank pixmap using tb_blank - */ - static void -pixmap_create_from_xpm(char **xpm, GdkPixmap **pixmap, GdkBitmap **mask) -{ - *pixmap = gdk_pixmap_colormap_create_from_xpm_d( - NULL, - gtk_widget_get_colormap(gui.mainwin), - mask, - NULL, - xpm); -} - -/* - * creates a pixmap by using a built-in number - */ - static void -pixmap_create_by_num(int pixmap_num, GdkPixmap **pixmap, GdkBitmap **mask) -{ - if (pixmap_num >= 0 && pixmap_num < (sizeof(built_in_pixmaps) - / sizeof(built_in_pixmaps[0]))) - pixmap_create_from_xpm(built_in_pixmaps[pixmap_num], pixmap, mask); -} - -/* - * Creates a pixmap by using the pixmap "name" found in 'runtimepath'/bitmaps/ - */ - static void -pixmap_create_by_dir(char_u *name, GdkPixmap **pixmap, GdkBitmap **mask) -{ - char_u full_pathname[MAXPATHL + 1]; - - if (gui_find_bitmap(name, full_pathname, "xpm") == OK) - *pixmap = gdk_pixmap_colormap_create_from_xpm( - NULL, - gtk_widget_get_colormap(gui.mainwin), - mask, - &gui.mainwin->style->bg[GTK_STATE_NORMAL], - (const char *)full_pathname); -} - -/* - * Creates a pixmap by using the pixmap "fname". - */ - static void -pixmap_create_from_file(char_u *fname, GdkPixmap **pixmap, GdkBitmap **mask) -{ - *pixmap = gdk_pixmap_colormap_create_from_xpm( - NULL, - gtk_widget_get_colormap(gui.mainwin), - mask, - &gui.mainwin->style->bg[GTK_STATE_NORMAL], - (const char *)fname); -} - -# endif /* FEAT_TOOLBAR && !HAVE_GTK2 */ - void gui_mch_add_menu_item(vimmenu_T *menu, int idx) { @@ -723,7 +448,6 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx) } else { -# ifdef HAVE_GTK2 char_u *text; char_u *tooltip; @@ -750,39 +474,6 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx) CONVERT_TO_UTF8_FREE(text); CONVERT_TO_UTF8_FREE(tooltip); - -# else /* !HAVE_GTK2 */ - - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; - - /* First try user specified bitmap, then builtin, the a blank. */ - if (menu->iconfile != NULL) - { - char_u buf[MAXPATHL + 1]; - - gui_find_iconfile(menu->iconfile, buf, "xpm"); - pixmap_create_from_file(buf, &pixmap, &mask); - } - if (pixmap == NULL && !menu->icon_builtin) - pixmap_create_by_dir(menu->name, &pixmap, &mask); - if (pixmap == NULL && menu->iconidx >= 0) - pixmap_create_by_num(menu->iconidx, &pixmap, &mask); - if (pixmap == NULL) - pixmap_create_from_xpm(tb_blank_xpm, &pixmap, &mask); - if (pixmap == NULL) - return; /* should at least have blank pixmap, but if not... */ - - menu->id = gtk_toolbar_insert_item( - toolbar, - (char *)(menu->dname), - (char *)(menu->strings[MENU_INDEX_TIP]), - (char *)(menu->dname), - gtk_pixmap_new(pixmap, mask), - GTK_SIGNAL_FUNC(menu_item_activate), - (gpointer)menu, - idx); -# endif /* !HAVE_GTK2 */ } } else @@ -837,45 +528,16 @@ gui_gtk_set_mnemonics(int enable) { vimmenu_T *menu; char_u *name; -# if !defined(HAVE_GTK2) && defined(GTK_USE_ACCEL) - guint accel_key; -# endif for (menu = root_menu; menu != NULL; menu = menu->next) { if (menu->id == NULL) continue; -# if defined(HAVE_GTK2) name = translate_mnemonic_tag(menu->name, enable); gtk_label_set_text_with_mnemonic(GTK_LABEL(menu->label), (const char *)name); vim_free(name); -# else -# if defined(GTK_USE_ACCEL) - name = translate_mnemonic_tag(menu->name, TRUE); - if (name != NULL) - { - accel_key = gtk_label_parse_uline(GTK_LABEL(menu->label), - (const char *)name); - if (accel_key != GDK_VoidSymbol) - gtk_widget_remove_accelerator(menu->id, gui.accel_group, - accel_key, GDK_MOD1_MASK); - if (enable && accel_key != GDK_VoidSymbol) - gtk_widget_add_accelerator(menu->id, "activate_item", - gui.accel_group, - accel_key, GDK_MOD1_MASK, - (GtkAccelFlags)0); - vim_free(name); - } - if (!enable) - { - name = translate_mnemonic_tag(menu->name, FALSE); - gtk_label_parse_uline(GTK_LABEL(menu->label), (const char *)name); - vim_free(name); - } -# endif -# endif } } @@ -903,58 +565,7 @@ gui_mch_toggle_tearoffs(int enable) } #endif /* FEAT_MENU */ - -#if defined(FEAT_TOOLBAR) && !defined(HAVE_GTK2) -/* - * Seems like there's a hole in the GTK Toolbar API: there's no provision for - * removing an item from the toolbar. Therefore I need to resort to going - * really deeply into the internal widget structures. - * - * <danielk> I'm not sure the statement above is true -- at least with - * GTK+ 2 one can just call gtk_widget_destroy() and be done with it. - * It is true though that you couldn't remove space items before GTK+ 2 - * (without digging into the internals that is). But the code below - * doesn't seem to handle those either. Well, it's obsolete anyway. - */ - static void -toolbar_remove_item_by_text(GtkToolbar *tb, const char *text) -{ - GtkContainer *container; - GList *childl; - GtkToolbarChild *gtbc; - - g_return_if_fail(tb != NULL); - g_return_if_fail(GTK_IS_TOOLBAR(tb)); - container = GTK_CONTAINER(&tb->container); - - for (childl = tb->children; childl; childl = childl->next) - { - gtbc = (GtkToolbarChild *)childl->data; - - if (gtbc->type != GTK_TOOLBAR_CHILD_SPACE - && strcmp(GTK_LABEL(gtbc->label)->label, text) == 0) - { - gboolean was_visible; - - was_visible = GTK_WIDGET_VISIBLE(gtbc->widget); - gtk_widget_unparent(gtbc->widget); - - tb->children = g_list_remove_link(tb->children, childl); - g_free(gtbc); - g_list_free(childl); - tb->num_children--; - - if (was_visible && GTK_WIDGET_VISIBLE(container)) - gtk_widget_queue_resize(GTK_WIDGET(container)); - - break; - } - } -} -#endif /* FEAT_TOOLBAR && !HAVE_GTK2 */ - - -#if defined(FEAT_TOOLBAR) && defined(HAVE_GTK2) +#if defined(FEAT_TOOLBAR) static int get_menu_position(vimmenu_T *menu) { @@ -969,7 +580,7 @@ get_menu_position(vimmenu_T *menu) return idx; } -#endif /* FEAT_TOOLBAR && HAVE_GTK2 */ +#endif /* FEAT_TOOLBAR */ #if defined(FEAT_TOOLBAR) || defined(PROTO) @@ -981,18 +592,12 @@ gui_mch_menu_set_tip(vimmenu_T *menu) { char_u *tooltip; -# ifdef HAVE_GTK2 tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]); if (tooltip == NULL || utf_valid_string(tooltip, NULL)) /* Only set the tooltip when it's valid utf-8. */ -# else - tooltip = menu->strings[MENU_INDEX_TIP]; -# endif gtk_tooltips_set_tip(GTK_TOOLBAR(gui.toolbar)->tooltips, menu->id, (const char *)tooltip, NULL); -# ifdef HAVE_GTK2 CONVERT_TO_UTF8_FREE(tooltip); -# endif } } #endif /* FEAT_TOOLBAR */ @@ -1008,16 +613,11 @@ gui_mch_destroy_menu(vimmenu_T *menu) # ifdef FEAT_TOOLBAR if (menu->parent != NULL && menu_is_toolbar(menu->parent->name)) { -# ifdef HAVE_GTK2 if (menu_is_separator(menu->name)) gtk_toolbar_remove_space(GTK_TOOLBAR(gui.toolbar), get_menu_position(menu)); else if (menu->id != NULL) gtk_widget_destroy(menu->id); -# else - toolbar_remove_item_by_text(GTK_TOOLBAR(gui.toolbar), - (const char *)menu->dname); -# endif } else # endif /* FEAT_TOOLBAR */ @@ -1054,21 +654,11 @@ gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max) adjustment->page_increment = size < 3L ? 1L : size - 2L; adjustment->step_increment = 1.0; -#ifdef HAVE_GTK2 g_signal_handler_block(GTK_OBJECT(adjustment), (gulong)sb->handler_id); -#else - gtk_signal_handler_block(GTK_OBJECT(adjustment), - (guint)sb->handler_id); -#endif gtk_adjustment_changed(adjustment); -#ifdef HAVE_GTK2 g_signal_handler_unblock(GTK_OBJECT(adjustment), (gulong)sb->handler_id); -#else - gtk_signal_handler_unblock(GTK_OBJECT(adjustment), - (guint)sb->handler_id); -#endif } } @@ -1108,7 +698,6 @@ adjustment_value_changed(GtkAdjustment *adjustment, gpointer data) */ if (sb != NULL) { -#ifdef HAVE_GTK2 dragging = TRUE; if (sb->wp != NULL) @@ -1139,9 +728,6 @@ adjustment_value_changed(GtkAdjustment *adjustment, gpointer data) } } } -#else - dragging = (GTK_RANGE(sb->id)->scroll_type == GTK_SCROLL_NONE); -#endif } gui_drag_scrollbar(sb, value, dragging); @@ -1193,7 +779,7 @@ gui_mch_destroy_scrollbar(scrollbar_T *sb) /* * Implementation of the file selector related stuff */ -#if defined(HAVE_GTK2) && GTK_CHECK_VERSION(2,4,0) +#if GTK_CHECK_VERSION(2,4,0) /* This has been disabled, because the GTK library rewrites * ~/.recently-used.xbel every time the main loop is quit. For Vim that means * on just about any event. */ @@ -1271,9 +857,7 @@ gui_mch_browse(int saving UNUSED, #endif char_u dirbuf[MAXPATHL]; -# ifdef HAVE_GTK2 title = CONVERT_TO_UTF8(title); -# endif /* GTK has a bug, it only works with an absolute path. */ if (initdir == NULL || *initdir == NUL) @@ -1343,19 +927,13 @@ gui_mch_browse(int saving UNUSED, gtk_file_selection_set_filename(GTK_FILE_SELECTION(gui.filedlg), (const gchar *)dirbuf); -# ifndef HAVE_GTK2 - gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin), - GTK_WIDGET(gui.filedlg), VW_POS_MOUSE); -# endif gtk_widget_show(gui.filedlg); while (gui.filedlg && GTK_WIDGET_DRAWABLE(gui.filedlg)) gtk_main_iteration_do(TRUE); #endif -# ifdef HAVE_GTK2 CONVERT_TO_UTF8_FREE(title); -# endif if (gui.browse_fname == NULL) return NULL; @@ -1363,8 +941,6 @@ gui_mch_browse(int saving UNUSED, return vim_strsave(shorten_fname1(gui.browse_fname)); } -#if defined(HAVE_GTK2) || defined(PROTO) - /* * Put up a directory selector * Returns the selected name in allocated memory, or NULL for Cancel. @@ -1428,544 +1004,11 @@ gui_mch_browsedir( return gui_mch_browse(0, title, NULL, NULL, initdir, NULL); # endif } -#endif #endif /* FEAT_BROWSE */ -#if defined(FEAT_GUI_DIALOG) && !defined(HAVE_GTK2) - -static char_u *dialog_textfield = NULL; -static GtkWidget *dialog_textentry; - - static void -dlg_destroy(GtkWidget *dlg) -{ - if (dialog_textfield != NULL) - { - const char *text; - - text = gtk_entry_get_text(GTK_ENTRY(dialog_textentry)); - vim_strncpy(dialog_textfield, (char_u *)text, IOSIZE - 1); - } - - /* Destroy the dialog, will break the waiting loop. */ - gtk_widget_destroy(dlg); -} - -# ifdef FEAT_GUI_GNOME - static int -gui_gnome_dialog( int type, - char_u *title, - char_u *message, - char_u *buttons, - int dfltbutton, - char_u *textfield) -{ - GtkWidget *dlg; - char *gdtype; - char_u *buttons_copy, *p, *next; - char **buttons_list; - int butcount, cur; - - /* make a copy, so that we can insert NULs */ - if ((buttons_copy = vim_strsave(buttons)) == NULL) - return -1; - - /* determine exact number of buttons and allocate array to hold them */ - for (butcount = 0, p = buttons; *p; p++) - { - if (*p == '\n') - butcount++; - } - butcount++; - buttons_list = g_new0(char *, butcount + 1); - - /* Add pixmap */ - switch (type) - { - case VIM_ERROR: - gdtype = GNOME_MESSAGE_BOX_ERROR; - break; - case VIM_WARNING: - gdtype = GNOME_MESSAGE_BOX_WARNING; - break; - case VIM_INFO: - gdtype = GNOME_MESSAGE_BOX_INFO; - break; - case VIM_QUESTION: - gdtype = GNOME_MESSAGE_BOX_QUESTION; - break; - default: - gdtype = GNOME_MESSAGE_BOX_GENERIC; - }; - - p = buttons_copy; - for (cur = 0; cur < butcount; ++cur) - { - for (next = p; *next; ++next) - { - if (*next == DLG_HOTKEY_CHAR) - STRMOVE(next, next + 1); - if (*next == DLG_BUTTON_SEP) - { - *next++ = NUL; - break; - } - } - - /* this should probably go into a table, but oh well */ - if (g_strcasecmp((char *)p, "Ok") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_OK); - else if (g_strcasecmp((char *)p, "Cancel") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_CANCEL); - else if (g_strcasecmp((char *)p, "Yes") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_YES); - else if (g_strcasecmp((char *)p, "No") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_NO); - else if (g_strcasecmp((char *)p, "Close") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_CLOSE); - else if (g_strcasecmp((char *)p, "Help") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_HELP); - else if (g_strcasecmp((char *)p, "Apply") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_APPLY); -#if 0 - /* - * these aren't really used that often anyway, but are listed here as - * placeholders in case we need them. - */ - else if (g_strcasecmp((char *)p, "Next") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_NEXT); - else if (g_strcasecmp((char *)p, "Prev") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_PREV); - else if (g_strcasecmp((char *)p, "Up") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_UP); - else if (g_strcasecmp((char *)p, "Down") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_DOWN); - else if (g_strcasecmp((char *)p, "Font") == 0) - buttons_list[cur] = g_strdup(GNOME_STOCK_BUTTON_FONT); -#endif - else - buttons_list[cur] = g_strdup((char *)p); - - if (*next == NUL) - break; - - p = next; - } - vim_free(buttons_copy); - - dlg = gnome_message_box_newv((const char *)message, - (const char *)gdtype, - (const char **)buttons_list); - for (cur = 0; cur < butcount; ++cur) - g_free(buttons_list[cur]); - g_free(buttons_list); - - dialog_textfield = textfield; - if (textfield != NULL) - { - /* Add text entry field */ - dialog_textentry = gtk_entry_new(); - gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dlg)->vbox), dialog_textentry, - TRUE, TRUE, 0); - gtk_entry_set_text(GTK_ENTRY(dialog_textentry), - (const gchar *)textfield); - gtk_entry_select_region(GTK_ENTRY(dialog_textentry), 0, - STRLEN(textfield)); - gtk_entry_set_max_length(GTK_ENTRY(dialog_textentry), IOSIZE - 1); - gtk_entry_set_position(GTK_ENTRY(dialog_textentry), STRLEN(textfield)); - gtk_widget_show(dialog_textentry); - gtk_window_set_focus(GTK_WINDOW(dlg), dialog_textentry); - } - - gtk_signal_connect_object(GTK_OBJECT(dlg), "destroy", - GTK_SIGNAL_FUNC(dlg_destroy), GTK_OBJECT(dlg)); - gnome_dialog_set_default(GNOME_DIALOG(dlg), dfltbutton + 1); - gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin), - GTK_WIDGET(dlg), VW_POS_MOUSE); - - return (1 + gnome_dialog_run_and_close(GNOME_DIALOG(dlg))); -} - -# endif /* FEAT_GUI_GNOME */ - -typedef struct _ButtonData -{ - int *status; - int index; - GtkWidget *dialog; -} ButtonData; - -typedef struct _CancelData -{ - int *status; - int ignore_enter; - GtkWidget *dialog; -} CancelData; - - static void -dlg_button_clicked(GtkWidget * widget, ButtonData *data) -{ - *(data->status) = data->index + 1; - dlg_destroy(data->dialog); -} - -/* - * This makes the Escape key equivalent to the cancel button. - */ - static int -dlg_key_press_event(GtkWidget *widget, GdkEventKey *event, CancelData *data) -{ - /* Ignore hitting Enter (or Space) when there is no default button. */ - if (data->ignore_enter && (event->keyval == GDK_Return - || event->keyval == ' ')) - return TRUE; - else /* A different key was pressed, return to normal behavior */ - data->ignore_enter = FALSE; - - if (event->keyval != GDK_Escape && event->keyval != GDK_Return) - return FALSE; - - /* The result value of 0 from a dialog is signaling cancelation. - * 1 means OK. */ - *(data->status) = (event->keyval == GDK_Return); - dlg_destroy(data->dialog); - - return TRUE; -} - -/* - * Callback function for when the dialog was destroyed by a window manager. - */ - static void -dlg_destroy_cb(int *p) -{ - *p = TRUE; /* set dialog_destroyed to break out of the loop */ - if (gtk_main_level() > 0) - gtk_main_quit(); -} - - int -gui_mch_dialog( int type, /* type of dialog */ - char_u *title, /* title of dialog */ - char_u *message, /* message text */ - char_u *buttons, /* names of buttons */ - int def_but, /* default button */ - char_u *textfield) /* text for textfield or NULL */ -{ - char_u *names; - char_u *p; - int i; - int butcount; - int dialog_status = -1; - int dialog_destroyed = FALSE; - int vertical; - - GtkWidget *dialog; - GtkWidget *frame; - GtkWidget *vbox; - GtkWidget *table; - GtkWidget *dialogmessage; - GtkWidget *action_area; - GtkWidget *sub_area; - GtkWidget *separator; - GtkAccelGroup *accel_group; - GtkWidget *pixmap; - GdkPixmap *icon = NULL; - GdkBitmap *mask = NULL; - char **icon_data = NULL; - - GtkWidget **button; - ButtonData *data; - CancelData cancel_data; - - /* if our pointer is currently hidden, then we should show it. */ - gui_mch_mousehide(FALSE); - -# ifdef FEAT_GUI_GNOME - /* If Gnome is available, use it for the dialog. */ - if (gtk_socket_id == 0) - return gui_gnome_dialog(type, title, message, buttons, def_but, - textfield); -# endif - - if (title == NULL) - title = (char_u *)_("Vim dialog..."); - - if ((type < 0) || (type > VIM_LAST_TYPE)) - type = VIM_GENERIC; - - /* Check 'v' flag in 'guioptions': vertical button placement. */ - vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL); - - dialog = gtk_window_new(GTK_WINDOW_DIALOG); - gtk_window_set_title(GTK_WINDOW(dialog), (const gchar *)title); - gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui.mainwin)); - gtk_widget_realize(dialog); - gdk_window_set_decorations(dialog->window, GDK_DECOR_BORDER); - gdk_window_set_functions(dialog->window, GDK_FUNC_MOVE); - - cancel_data.status = &dialog_status; - cancel_data.dialog = dialog; - gtk_signal_connect_after(GTK_OBJECT(dialog), "key_press_event", - GTK_SIGNAL_FUNC(dlg_key_press_event), - (gpointer) &cancel_data); - /* Catch the destroy signal, otherwise we don't notice a window manager - * destroying the dialog window. */ - gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy", - GTK_SIGNAL_FUNC(dlg_destroy_cb), - (gpointer)&dialog_destroyed); - - gtk_grab_add(dialog); - - /* this makes it look beter on Motif style window managers */ - frame = gtk_frame_new(NULL); - gtk_container_add(GTK_CONTAINER(dialog), frame); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - table = gtk_table_new(1, 3, FALSE); - gtk_table_set_row_spacings(GTK_TABLE(table), 4); - gtk_table_set_col_spacings(GTK_TABLE(table), 8); - gtk_container_border_width(GTK_CONTAINER(table), 4); - gtk_box_pack_start(GTK_BOX(vbox), table, 4, 4, 0); - gtk_widget_show(table); - - /* Add pixmap */ - switch (type) - { - case VIM_GENERIC: - icon_data = generic_xpm; - break; - case VIM_ERROR: - icon_data = error_xpm; - break; - case VIM_WARNING: - icon_data = alert_xpm; - break; - case VIM_INFO: - icon_data = info_xpm; - break; - case VIM_QUESTION: - icon_data = quest_xpm; - break; - default: - icon_data = generic_xpm; - }; - icon = gdk_pixmap_colormap_create_from_xpm_d(NULL, - gtk_widget_get_colormap(dialog), - &mask, NULL, icon_data); - if (icon) - { - pixmap = gtk_pixmap_new(icon, mask); - /* gtk_misc_set_alignment(GTK_MISC(pixmap), 0.5, 0.5); */ - gtk_table_attach_defaults(GTK_TABLE(table), pixmap, 0, 1, 0, 1); - gtk_widget_show(pixmap); - } - - /* Add label */ - dialogmessage = gtk_label_new((const gchar *)message); - gtk_table_attach_defaults(GTK_TABLE(table), dialogmessage, 1, 2, 0, 1); - gtk_widget_show(dialogmessage); - - dialog_textfield = textfield; - if (textfield != NULL) - { - /* Add text entry field */ - dialog_textentry = gtk_entry_new(); - gtk_widget_set_usize(dialog_textentry, 400, -2); - gtk_box_pack_start(GTK_BOX(vbox), dialog_textentry, TRUE, TRUE, 0); - gtk_entry_set_text(GTK_ENTRY(dialog_textentry), - (const gchar *)textfield); - gtk_entry_select_region(GTK_ENTRY(dialog_textentry), 0, - STRLEN(textfield)); - gtk_entry_set_max_length(GTK_ENTRY(dialog_textentry), IOSIZE - 1); - gtk_entry_set_position(GTK_ENTRY(dialog_textentry), STRLEN(textfield)); - gtk_widget_show(dialog_textentry); - } - - /* Add box for buttons */ - action_area = gtk_hbox_new(FALSE, 0); - gtk_container_border_width(GTK_CONTAINER(action_area), 4); - gtk_box_pack_end(GTK_BOX(vbox), action_area, FALSE, TRUE, 0); - gtk_widget_show(action_area); - - /* Add a [vh]box in the hbox to center the buttons in the dialog. */ - if (vertical) - sub_area = gtk_vbox_new(FALSE, 0); - else - sub_area = gtk_hbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(sub_area), 0); - gtk_box_pack_start(GTK_BOX(action_area), sub_area, TRUE, FALSE, 0); - gtk_widget_show(sub_area); - - /* - * Create the buttons. - */ - - /* - * Translate the Vim accelerator character into an underscore for GTK+. - * Double underscores to keep them in the label. - */ - /* count the number of underscores */ - i = 1; - for (p = buttons; *p; ++p) - if (*p == '_') - ++i; - - /* make a copy of "buttons" with the translated characters */ - names = alloc(STRLEN(buttons) + i); - if (names == NULL) - return -1; - - p = names; - for (i = 0; buttons[i]; ++i) - { - if (buttons[i] == DLG_HOTKEY_CHAR) - *p++ = '_'; - else - { - if (buttons[i] == '_') - *p++ = '_'; - *p++ = buttons[i]; - } - } - *p = NUL; - - /* Count the number of buttons and allocate button[] and data[]. */ - butcount = 1; - for (p = names; *p; ++p) - if (*p == DLG_BUTTON_SEP) - ++butcount; - button = (GtkWidget **)alloc((unsigned)(butcount * sizeof(GtkWidget *))); - data = (ButtonData *)alloc((unsigned)(butcount * sizeof(ButtonData))); - if (button == NULL || data == NULL) - { - vim_free(names); - vim_free(button); - vim_free(data); - return -1; - } - - /* Attach the new accelerator group to the window. */ - accel_group = gtk_accel_group_new(); - gtk_accel_group_attach(accel_group, GTK_OBJECT(dialog)); - - p = names; - for (butcount = 0; *p; ++butcount) - { - char_u *next; - GtkWidget *label; -# ifdef GTK_USE_ACCEL - guint accel_key; -# endif - - /* Chunk out this single button. */ - for (next = p; *next; ++next) - { - if (*next == DLG_BUTTON_SEP) - { - *next++ = NUL; - break; - } - } - - button[butcount] = gtk_button_new(); - GTK_WIDGET_SET_FLAGS(button[butcount], GTK_CAN_DEFAULT); - - label = gtk_accel_label_new(""); - gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(label), dialog); - -# ifdef GTK_USE_ACCEL - accel_key = gtk_label_parse_uline(GTK_LABEL(label), (const gchar *)p); - /* Don't add accelator if 'winaltkeys' is "no". */ - if (accel_key != GDK_VoidSymbol) - { - gtk_widget_add_accelerator(button[butcount], - "clicked", - accel_group, - accel_key, 0, - (GtkAccelFlags)0); - } -# else - (void)gtk_label_parse_uline(GTK_LABEL(label), (const gchar *)p); -# endif - - gtk_container_add(GTK_CONTAINER(button[butcount]), label); - gtk_widget_show_all(button[butcount]); - - data[butcount].status = &dialog_status; - data[butcount].index = butcount; - data[butcount].dialog = dialog; - gtk_signal_connect(GTK_OBJECT(button[butcount]), - (const char *)"clicked", - GTK_SIGNAL_FUNC(dlg_button_clicked), - (gpointer) &data[butcount]); - - gtk_box_pack_start(GTK_BOX(sub_area), button[butcount], - TRUE, FALSE, 0); - p = next; - } - - vim_free(names); - - cancel_data.ignore_enter = FALSE; - if (butcount > 0) - { - --def_but; /* 1 is first button */ - if (def_but >= butcount) - def_but = -1; - if (def_but >= 0) - { - gtk_widget_grab_focus(button[def_but]); - gtk_widget_grab_default(button[def_but]); - } - else - /* No default, ignore hitting Enter. */ - cancel_data.ignore_enter = TRUE; - } - - if (textfield != NULL) - gtk_window_set_focus(GTK_WINDOW(dialog), dialog_textentry); - - separator = gtk_hseparator_new(); - gtk_box_pack_end(GTK_BOX(vbox), separator, FALSE, TRUE, 0); - gtk_widget_show(separator); - - dialog_status = -1; - - gui_gtk_position_in_parent(GTK_WIDGET(gui.mainwin), - GTK_WIDGET(dialog), VW_POS_MOUSE); - - gtk_widget_show(dialog); - - /* loop here until the dialog goes away */ - while (dialog_status == -1 && !dialog_destroyed |