diff --git a/plugins/filebrowser.c b/plugins/filebrowser.c index d133a20866..85013f16fa 100644 --- a/plugins/filebrowser.c +++ b/plugins/filebrowser.c @@ -26,6 +26,7 @@ #endif #include "geanyplugin.h" +#include "gtkcompat.h" #include #include @@ -280,7 +281,7 @@ static void refresh(void) utf8_dir = utils_get_utf8_from_locale(current_dir); gtk_entry_set_text(GTK_ENTRY(path_entry), utf8_dir); gtk_widget_set_tooltip_text(path_entry, utf8_dir); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(path_combo), utf8_dir, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(path_combo), utf8_dir, 0); g_free(utf8_dir); add_top_level_entry(); /* ".." item */ @@ -804,7 +805,7 @@ static void on_filter_activate(GtkEntry *entry, gpointer user_data) { clear_filter(); } - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(filter_combo), NULL, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(filter_combo), NULL, 0); refresh(); } @@ -898,7 +899,7 @@ static GtkWidget *make_filterbar(void) label = gtk_label_new(_("Filter:")); - filter_combo = gtk_combo_box_entry_new_text(); + filter_combo = gtk_combo_box_text_new_with_entry(); filter_entry = gtk_bin_get_child(GTK_BIN(filter_combo)); ui_entry_add_clear_icon(GTK_ENTRY(filter_entry)); @@ -1092,7 +1093,7 @@ void plugin_init(GeanyData *data) filterbar = make_filterbar(); gtk_box_pack_start(GTK_BOX(file_view_vbox), filterbar, FALSE, FALSE, 0); - path_combo = gtk_combo_box_entry_new_text(); + path_combo = gtk_combo_box_text_new_with_entry(); gtk_box_pack_start(GTK_BOX(file_view_vbox), path_combo, FALSE, FALSE, 2); g_signal_connect(path_combo, "changed", G_CALLBACK(ui_combo_box_changed), NULL); path_entry = gtk_bin_get_child(GTK_BIN(path_combo)); diff --git a/plugins/saveactions.c b/plugins/saveactions.c index 0303593980..1842b44f04 100644 --- a/plugins/saveactions.c +++ b/plugins/saveactions.c @@ -430,8 +430,8 @@ static void configure_response_cb(GtkDialog *dialog, gint response, G_GNUC_UNUSE GTK_TOGGLE_BUTTON(pref_widgets.autosave_save_all_radio2)); g_free(instantsave_default_ft); - instantsave_default_ft = gtk_combo_box_get_active_text( - GTK_COMBO_BOX(pref_widgets.instantsave_ft_combo)); + instantsave_default_ft = gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(pref_widgets.instantsave_ft_combo)); text_dir = gtk_entry_get_text(GTK_ENTRY(pref_widgets.backupcopy_entry_dir)); text_time = gtk_entry_get_text(GTK_ENTRY(pref_widgets.backupcopy_entry_time)); @@ -621,13 +621,13 @@ GtkWidget *plugin_configure(GtkDialog *dialog) gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(inner_vbox), label, FALSE, FALSE, 0); - pref_widgets.instantsave_ft_combo = combo = gtk_combo_box_new_text(); + pref_widgets.instantsave_ft_combo = combo = gtk_combo_box_text_new(); i = 0; foreach_slist(node, filetypes_get_sorted_by_name()) { GeanyFiletype *ft = node->data; - gtk_combo_box_append_text(GTK_COMBO_BOX(combo), ft->name); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ft->name); if (utils_str_equal(ft->name, instantsave_default_ft)) gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i); diff --git a/src/Makefile.am b/src/Makefile.am index f078cdd211..d558a0aae7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,7 @@ geany_include_HEADERS = \ encodings.h \ filetypes.h \ geany.h \ + gtkcompat.h \ highlighting.h \ keybindings.h \ msgwindow.h \ diff --git a/src/dialogs.c b/src/dialogs.c index d8071db5f4..5ef02fb511 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -55,6 +55,7 @@ #include "build.h" #include "main.h" #include "project.h" +#include "gtkcompat.h" enum @@ -326,7 +327,7 @@ static GtkWidget *add_file_open_extra_widget(GtkWidget *dialog) (GtkAttachOptions) (0), 4, 5); /* the ebox is for the tooltip, because gtk_combo_box can't show tooltips */ filetype_ebox = gtk_event_box_new(); - filetype_combo = gtk_combo_box_new_text(); + filetype_combo = gtk_combo_box_text_new(); gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(filetype_combo), 2); gtk_widget_set_tooltip_text(filetype_ebox, _("Explicitly defines a filetype for the file, if it would not be detected by filename extension.\nNote if you choose multiple files, they will all be opened with the chosen filetype.")); @@ -384,7 +385,7 @@ static GtkWidget *create_open_file_dialog(void) gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), add_file_open_extra_widget(dialog)); filetype_combo = ui_lookup_widget(dialog, "filetype_combo"); - gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), _("Detect by file extension")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(filetype_combo), _("Detect by file extension")); /* add FileFilters(start with "All Files") */ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filetypes_create_file_filter(filetypes[GEANY_FILETYPES_NONE])); @@ -397,7 +398,7 @@ static GtkWidget *create_open_file_dialog(void) if (G_UNLIKELY(ft->id == GEANY_FILETYPES_NONE)) continue; - gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), ft->title); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(filetype_combo), ft->title); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filetypes_create_file_filter(ft)); } gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), 0); @@ -971,7 +972,7 @@ on_input_dialog_response(GtkDialog *dialog, gint response, GtkWidget *entry) if (persistent) { GtkWidget *combo = (GtkWidget *) g_object_get_data(G_OBJECT(dialog), "combo"); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(combo), str, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(combo), str, 0); } input_cb(str); } @@ -995,7 +996,7 @@ static void add_input_widgets(GtkWidget *dialog, GtkWidget *vbox, if (persistent) /* remember previous entry text in a combo box */ { - GtkWidget *combo = gtk_combo_box_entry_new_text(); + GtkWidget *combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); diff --git a/src/gtkcompat.h b/src/gtkcompat.h index aca3b8e5ce..cc6689b191 100644 --- a/src/gtkcompat.h +++ b/src/gtkcompat.h @@ -31,6 +31,37 @@ G_BEGIN_DECLS +/* GtkComboBoxText */ +/* This is actually available in GTK 2.24, but we expose GtkComboBoxText in the + * API so we don't want the type to change for no good reason (although this + * should probably be harmless since it's only a derivated type). However, since + * a plugin needs to be rebuilt and tuned to work with GTK3 we don't mind that + * a type changes between the GTK2 and GTK3 version */ +#if ! GTK_CHECK_VERSION(3, 0, 0) +/* undef those not to get warnings about redefinitions under GTK 2.24 */ +# undef GTK_COMBO_BOX_TEXT +# undef GTK_COMBO_BOX_TEXT_CLASS +# undef GTK_COMBO_BOX_TEXT_GET_CLASS +# undef GTK_IS_COMBO_BOX_TEXT +# undef GTK_IS_COMBO_BOX_TEXT_CLASS +# undef GTK_TYPE_COMBO_BOX_TEXT + +# define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX +# define GTK_COMBO_BOX_TEXT_CLASS GTK_COMBO_BOX_CLASS +# define GTK_COMBO_BOX_TEXT_GET_CLASS GTK_COMBO_BOX_GET_CLASS +# define GTK_IS_COMBO_BOX_TEXT GTK_IS_COMBO_BOX +# define GTK_IS_COMBO_BOX_TEXT_CLASS GTK_IS_COMBO_BOX_CLASS +# define GTK_TYPE_COMBO_BOX_TEXT GTK_TYPE_COMBO_BOX +# define GtkComboBoxText GtkComboBox +# define gtk_combo_box_text_new gtk_combo_box_new_text +# define gtk_combo_box_text_new_with_entry gtk_combo_box_entry_new_text +# define gtk_combo_box_text_append_text gtk_combo_box_append_text +# define gtk_combo_box_text_insert_text gtk_combo_box_insert_text +# define gtk_combo_box_text_prepend_text gtk_combo_box_prepend_text +# define gtk_combo_box_text_remove gtk_combo_box_remove_text +# define gtk_combo_box_text_get_active_text gtk_combo_box_get_active_text +#endif + /* GtkDialog */ /* GTK 2.22 deprecated dialog separators and 3.0 removed them * We keep those however in case 2.16 has separators by default */ diff --git a/src/plugindata.h b/src/plugindata.h index 0b2c2f679b..6356ef6108 100644 --- a/src/plugindata.h +++ b/src/plugindata.h @@ -41,6 +41,7 @@ G_BEGIN_DECLS #include "editor.h" /* GeanyIndentType */ #include "build.h" /* GeanyBuildGroup, GeanyBuildSource, GeanyBuildCmdEntries enums */ +#include "gtkcompat.h" /** The Application Programming Interface (API) version, incremented @@ -476,7 +477,7 @@ typedef struct UIUtilsFuncs void (*ui_widget_modify_font_from_string) (GtkWidget *widget, const gchar *str); gboolean (*ui_is_keyval_enter_or_return) (guint keyval); gint (*ui_get_gtk_settings_integer) (const gchar *property_name, gint default_value); - void (*ui_combo_box_add_to_history) (GtkComboBoxEntry *combo_entry, + void (*ui_combo_box_add_to_history) (GtkComboBoxText *combo_entry, const gchar *text, gint history_len); void (*ui_menu_add_document_items_sorted) (GtkMenu *menu, struct GeanyDocument *active, GCallback callback, GCompareFunc compare_func); diff --git a/src/search.c b/src/search.c index 51741b6e5c..b54a0d765e 100644 --- a/src/search.c +++ b/src/search.c @@ -456,7 +456,7 @@ static void create_find_dialog(void) label = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - entry = gtk_combo_box_entry_new_text(); + entry = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry))), 50); @@ -618,14 +618,14 @@ static void create_replace_dialog(void) label_replace = gtk_label_new_with_mnemonic(_("Replace wit_h:")); gtk_misc_set_alignment(GTK_MISC(label_replace), 0, 0.5); - entry_find = gtk_combo_box_entry_new_text(); + entry_find = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_find)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label_find), entry_find); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_find))), 50); ui_hookup_widget(replace_dlg.dialog, entry_find, "entry_find"); replace_dlg.find_entry = gtk_bin_get_child(GTK_BIN(entry_find)); - entry_replace = gtk_combo_box_entry_new_text(); + entry_replace = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_replace)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label_replace), entry_replace); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_replace))), 50); @@ -854,7 +854,7 @@ static void create_fif_dialog(void) label = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - combo = gtk_combo_box_entry_new_text(); + combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); @@ -878,7 +878,7 @@ static void create_fif_dialog(void) ui_hookup_widget(fif_dlg.dialog, combo_files_mode, "combo_files_mode"); fif_dlg.files_mode_combo = combo_files_mode; - fcombo = gtk_combo_box_entry_new_text(); + fcombo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(fcombo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); @@ -897,7 +897,7 @@ static void create_fif_dialog(void) label1 = gtk_label_new_with_mnemonic(_("_Directory:")); gtk_misc_set_alignment(GTK_MISC(label1), 0, 0.5); - dir_combo = gtk_combo_box_entry_new_text(); + dir_combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(dir_combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label1), entry); @@ -915,11 +915,11 @@ static void create_fif_dialog(void) label2 = gtk_label_new_with_mnemonic(_("E_ncoding:")); gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5); - e_combo = gtk_combo_box_new_text(); + e_combo = gtk_combo_box_text_new(); for (i = 0; i < GEANY_ENCODINGS_MAX; i++) { encoding_string = encodings_to_string(&encodings[i]); - gtk_combo_box_append_text(GTK_COMBO_BOX(e_combo), encoding_string); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(e_combo), encoding_string); g_free(encoding_string); } gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(e_combo), 3); @@ -1037,7 +1037,7 @@ void search_show_find_in_files_dialog(const gchar *dir) * (in create_fif_dialog() it would fail if a project is opened after dialog creation) */ if (app->project != NULL && NZV(app->project->base_path)) { - ui_combo_box_prepend_text_once(GTK_COMBO_BOX(fif_dlg.dir_combo), + ui_combo_box_prepend_text_once(GTK_COMBO_BOX_TEXT(fif_dlg.dir_combo), app->project->base_path); } @@ -1056,8 +1056,7 @@ void search_show_find_in_files_dialog(const gchar *dir) if (doc == last_doc && cur_dir && utils_str_equal(cur_dir, last_cur_dir)) { /* in case the user now wants the current directory, add it to history */ - ui_combo_box_add_to_history( - GTK_COMBO_BOX_ENTRY(fif_dlg.dir_combo), cur_dir, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(fif_dlg.dir_combo), cur_dir, 0); SETPTR(cur_dir, NULL); } else @@ -1242,7 +1241,7 @@ on_find_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) if (! utils_str_replace_escape(search_data.text, FALSE)) goto fail; } - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(user_data), search_data.original_text, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(user_data), search_data.original_text, 0); switch (response) { @@ -1379,9 +1378,9 @@ on_replace_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) goto fail; } - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY( + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT( gtk_widget_get_parent(replace_dlg.find_entry)), original_find, 0); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY( + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT( gtk_widget_get_parent(replace_dlg.replace_entry)), original_replace, 0); switch (response) @@ -1521,9 +1520,9 @@ on_find_in_files_dialog_response(GtkDialog *dialog, gint response, if (search_find_in_files(search_text, locale_dir, opts->str, enc)) { - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(search_combo), search_text, 0); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(fif_dlg.files_combo), NULL, 0); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(dir_combo), utf8_dir, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(search_combo), search_text, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(fif_dlg.files_combo), NULL, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(dir_combo), utf8_dir, 0); gtk_widget_hide(fif_dlg.dialog); } g_free(locale_dir); diff --git a/src/stash.c b/src/stash.c index 1e013c5fbb..cadfacfccc 100644 --- a/src/stash.c +++ b/src/stash.c @@ -85,6 +85,26 @@ #include "stash.h" +/* GTK3 removed ComboBoxEntry, but we need a value to differentiate combo box with and + * without entries, and it must not collide with other GTypes */ +#ifdef GTK_TYPE_COMBO_BOX_ENTRY +# define TYPE_COMBO_BOX_ENTRY GTK_TYPE_COMBO_BOX_ENTRY +#else /* !GTK_TYPE_COMBO_BOX_ENTRY */ +# define TYPE_COMBO_BOX_ENTRY get_combo_box_entry_type() +static GType get_combo_box_entry_type(void) +{ + static volatile gsize type = 0; + if (g_once_init_enter(&type)) + { + GType g_type = g_type_register_static_simple(GTK_TYPE_COMBO_BOX, "dummy-combo-box-entry", + sizeof(GtkComboBoxClass), NULL, sizeof(GtkComboBox), NULL, G_TYPE_FLAG_ABSTRACT); + g_once_init_leave(&type, g_type); + } + return type; +} +#endif /* !GTK_TYPE_COMBO_BOX_ENTRY */ + + struct StashPref { GType setting_type; /* e.g. G_TYPE_INT */ @@ -696,7 +716,7 @@ static void pref_action(PrefAction action, StashGroup *group, GtkWidget *owner) handle_spin_button(widget, entry, action); else if (entry->widget_type == GTK_TYPE_COMBO_BOX) handle_combo_box(widget, entry, action); - else if (entry->widget_type == GTK_TYPE_COMBO_BOX_ENTRY) + else if (entry->widget_type == TYPE_COMBO_BOX_ENTRY) handle_combo_box_entry(widget, entry, action); else if (entry->widget_type == GTK_TYPE_ENTRY) handle_entry(widget, entry, action); @@ -861,7 +881,7 @@ void stash_group_add_combo_box_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_STRING, setting, key_name, (gpointer)default_value, - GTK_TYPE_COMBO_BOX_ENTRY, widget_id); + TYPE_COMBO_BOX_ENTRY, widget_id); } diff --git a/src/ui_utils.c b/src/ui_utils.c index ad0384f7d7..b353316678 100644 --- a/src/ui_utils.c +++ b/src/ui_utils.c @@ -1544,7 +1544,7 @@ static gboolean tree_model_find_text(GtkTreeModel *model, * @param combo_entry . * @param text Text to add, or @c NULL for current entry text. * @param history_len Max number of items, or @c 0 for default. */ -void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, +void ui_combo_box_add_to_history(GtkComboBoxText *combo_entry, const gchar *text, gint history_len) { GtkComboBox *combo = GTK_COMBO_BOX(combo_entry); @@ -1563,7 +1563,7 @@ void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, { gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } - gtk_combo_box_prepend_text(combo, text); + gtk_combo_box_text_prepend_text(combo_entry, text); /* limit history */ path = gtk_tree_path_new_from_indices(history_len, -1); @@ -1575,18 +1575,18 @@ void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, } -/* Same as gtk_combo_box_prepend_text(), except that text is only prepended if it not already +/* Same as gtk_combo_box_text_prepend_text(), except that text is only prepended if it not already * exists in the combo's model. */ -void ui_combo_box_prepend_text_once(GtkComboBox *combo, const gchar *text) +void ui_combo_box_prepend_text_once(GtkComboBoxText *combo, const gchar *text) { GtkTreeModel *model; GtkTreeIter iter; - model = gtk_combo_box_get_model(combo); + model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); if (tree_model_find_text(model, &iter, 0, text)) return; /* don't prepend duplicate */ - gtk_combo_box_prepend_text(combo, text); + gtk_combo_box_text_prepend_text(combo, text); } diff --git a/src/ui_utils.h b/src/ui_utils.h index 130c6d59b9..4d1f61fcfd 100644 --- a/src/ui_utils.h +++ b/src/ui_utils.h @@ -22,6 +22,8 @@ #ifndef GEANY_UI_UTILS_H #define GEANY_UI_UTILS_H 1 +#include "gtkcompat.h" + G_BEGIN_DECLS @@ -195,10 +197,10 @@ GtkWidget *ui_image_menu_item_new(const gchar *stock_id, const gchar *label); void ui_hbutton_box_copy_layout(GtkButtonBox *master, GtkButtonBox *copy); -void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, +void ui_combo_box_add_to_history(GtkComboBoxText *combo_entry, const gchar *text, gint history_len); -void ui_combo_box_prepend_text_once(GtkComboBox *combo, const gchar *text); +void ui_combo_box_prepend_text_once(GtkComboBoxText *combo, const gchar *text); GtkWidget *ui_path_box_new(const gchar *title, GtkFileChooserAction action, GtkEntry *entry);