Merge branch 'unified-encoding-combo-boxes'

This commit is contained in:
Colomban Wendling 2014-04-15 15:57:13 +02:00
commit aeab183ef2
9 changed files with 264 additions and 204 deletions

View File

@ -433,12 +433,6 @@
</object>
</child>
</object>
<object class="GtkListStore" id="encoding_list">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="eol_list">
<columns>
<!-- column-name text -->
@ -4368,12 +4362,8 @@
<object class="GtkComboBox" id="combo_new_encoding">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">encoding_list</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext6"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
<object class="GtkCellRendererText" id="combo_new_encoding_renderer"/>
</child>
</object>
</child>
@ -4434,12 +4424,8 @@
<object class="GtkComboBox" id="combo_open_encoding">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">encoding_list</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext7"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
<object class="GtkCellRendererText" id="combo_open_encoding_renderer"/>
</child>
</object>
</child>

View File

@ -125,8 +125,6 @@ static void open_file_dialog_handle_response(GtkWidget *dialog, gint response)
if (response == GTK_RESPONSE_ACCEPT || response == GEANY_RESPONSE_VIEW)
{
GSList *filelist;
GtkTreeModel *encoding_model;
GtkTreeIter encoding_iter;
GeanyFiletype *ft = NULL;
const gchar *charset = NULL;
GtkWidget *expander = ui_lookup_widget(dialog, "more_options_expander");
@ -142,9 +140,7 @@ static void open_file_dialog_handle_response(GtkWidget *dialog, gint response)
if (filesel_state.open.filetype_idx > 0)
ft = g_slist_nth_data(filetypes_by_title, (guint) filesel_state.open.filetype_idx);
encoding_model = gtk_combo_box_get_model(GTK_COMBO_BOX(encoding_combo));
gtk_combo_box_get_active_iter(GTK_COMBO_BOX(encoding_combo), &encoding_iter);
gtk_tree_model_get(encoding_model, &encoding_iter, 0, &filesel_state.open.encoding_idx, -1);
filesel_state.open.encoding_idx = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(encoding_combo));
if (filesel_state.open.encoding_idx >= 0 && filesel_state.open.encoding_idx < GEANY_ENCODINGS_MAX)
charset = encodings[filesel_state.open.encoding_idx].charset;
@ -182,97 +178,6 @@ on_file_open_check_hidden_toggled(GtkToggleButton *togglebutton, GtkWidget *dial
}
static gint encoding_combo_store_sort_func(GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer data)
{
gboolean a_has_child = gtk_tree_model_iter_has_child(model, a);
gboolean b_has_child = gtk_tree_model_iter_has_child(model, b);
gchar *a_string;
gchar *b_string;
gint cmp_res;
if (a_has_child != b_has_child)
return a_has_child ? -1 : 1;
gtk_tree_model_get(model, a, 1, &a_string, -1);
gtk_tree_model_get(model, b, 1, &b_string, -1);
cmp_res = strcmp(a_string, b_string);
g_free(a_string);
g_free(b_string);
return cmp_res;
}
static GtkTreeStore *create_encoding_combo_store(GtkTreeIter *iter_detect)
{
GtkTreeStore *store;
GtkTreeIter iter_current, iter_westeuro, iter_easteuro, iter_eastasian, iter_asian,
iter_utf8, iter_middleeast;
GtkTreeIter *iter_parent;
gchar *encoding_string;
gint i;
store = gtk_tree_store_new(2, G_TYPE_INT, G_TYPE_STRING);
gtk_tree_store_append(store, iter_detect, NULL);
gtk_tree_store_set(store, iter_detect, 0, GEANY_ENCODINGS_MAX, 1, _("Detect from file"), -1);
gtk_tree_store_append(store, &iter_westeuro, NULL);
gtk_tree_store_set(store, &iter_westeuro, 0, -1, 1, _("West European"), -1);
gtk_tree_store_append(store, &iter_easteuro, NULL);
gtk_tree_store_set(store, &iter_easteuro, 0, -1, 1, _("East European"), -1);
gtk_tree_store_append(store, &iter_eastasian, NULL);
gtk_tree_store_set(store, &iter_eastasian, 0, -1, 1, _("East Asian"), -1);
gtk_tree_store_append(store, &iter_asian, NULL);
gtk_tree_store_set(store, &iter_asian, 0, -1, 1, _("SE & SW Asian"), -1);
gtk_tree_store_append(store, &iter_middleeast, NULL);
gtk_tree_store_set(store, &iter_middleeast, 0, -1, 1, _("Middle Eastern"), -1);
gtk_tree_store_append(store, &iter_utf8, NULL);
gtk_tree_store_set(store, &iter_utf8, 0, -1, 1, _("Unicode"), -1);
for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
{
switch (encodings[i].group)
{
case WESTEUROPEAN: iter_parent = &iter_westeuro; break;
case EASTEUROPEAN: iter_parent = &iter_easteuro; break;
case EASTASIAN: iter_parent = &iter_eastasian; break;
case ASIAN: iter_parent = &iter_asian; break;
case MIDDLEEASTERN: iter_parent = &iter_middleeast; break;
case UNICODE: iter_parent = &iter_utf8; break;
case NONE:
default: iter_parent = NULL;
}
gtk_tree_store_append(store, &iter_current, iter_parent);
encoding_string = encodings_to_string(&encodings[i]);
gtk_tree_store_set(store, &iter_current, 0, i, 1, encoding_string, -1);
g_free(encoding_string);
/* restore the saved state */
if (i == filesel_state.open.encoding_idx)
*iter_detect = iter_current;
}
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 1, GTK_SORT_ASCENDING);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), 1, encoding_combo_store_sort_func, NULL, NULL);
return store;
}
static void encoding_combo_cell_data_func(GtkCellLayout *cell_layout,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data)
{
gboolean sensitive = !gtk_tree_model_iter_has_child(tree_model, iter);
g_object_set(cell, "sensitive", sensitive, NULL);
}
static GtkWidget *add_file_open_extra_widget(GtkWidget *dialog)
{
GtkWidget *expander, *vbox, *table, *check_hidden;
@ -304,7 +209,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 */
encoding_ebox = gtk_event_box_new();
encoding_combo = gtk_combo_box_new();
encoding_combo = ui_create_encodings_combo_box(TRUE, GEANY_ENCODINGS_MAX);
gtk_widget_set_tooltip_text(encoding_ebox,
_("Explicitly defines an encoding for the file, if it would not be detected. This is useful when you know that the encoding of a file cannot be detected correctly by Geany.\nNote if you choose multiple files, they will all be opened with the chosen encoding."));
gtk_container_add(GTK_CONTAINER(encoding_ebox), encoding_combo);
@ -345,10 +250,8 @@ static GtkWidget *add_file_open_extra_widget(GtkWidget *dialog)
static GtkWidget *create_open_file_dialog(void)
{
GtkWidget *dialog;
GtkWidget *filetype_combo, *encoding_combo;
GtkWidget *filetype_combo;
GtkWidget *viewbtn;
GtkCellRenderer *encoding_renderer;
GtkTreeIter encoding_iter;
GSList *node;
dialog = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(main_widgets.window),
@ -396,17 +299,6 @@ static GtkWidget *create_open_file_dialog(void)
gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(filetype_combo), 3);
gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), 0);
/* fill encoding combo box */
encoding_combo = ui_lookup_widget(dialog, "encoding_combo");
gtk_combo_box_set_model(GTK_COMBO_BOX(encoding_combo), GTK_TREE_MODEL(
create_encoding_combo_store(&encoding_iter)));
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(encoding_combo), &encoding_iter);
encoding_renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(encoding_combo), encoding_renderer, TRUE);
gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(encoding_combo), encoding_renderer, "text", 1);
gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(encoding_combo), encoding_renderer,
encoding_combo_cell_data_func, NULL, NULL);
g_signal_connect(dialog, "notify::show-hidden",
G_CALLBACK(on_file_open_show_hidden_notify), NULL);
@ -419,6 +311,7 @@ static void open_file_dialog_apply_settings(GtkWidget *dialog)
static gboolean initialized = FALSE;
GtkWidget *check_hidden = ui_lookup_widget(dialog, "check_hidden");
GtkWidget *filetype_combo = ui_lookup_widget(dialog, "filetype_combo");
GtkWidget *encoding_combo = ui_lookup_widget(dialog, "encoding_combo");
GtkWidget *expander = ui_lookup_widget(dialog, "more_options_expander");
/* we can't know the initial position of combo boxes, so retreive it the first time */
@ -436,7 +329,7 @@ static void open_file_dialog_apply_settings(GtkWidget *dialog)
}
gtk_expander_set_expanded(GTK_EXPANDER(expander), filesel_state.open.more_options_visible);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_hidden), filesel_state.open.show_hidden);
/* encoding combo is restored at creating time, see create_encoding_combo_store() */
ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(encoding_combo), filesel_state.open.encoding_idx);
}

View File

@ -497,6 +497,123 @@ void encodings_init(void)
}
static gint encoding_combo_store_sort_func(GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer data)
{
gboolean a_has_child = gtk_tree_model_iter_has_child(model, a);
gboolean b_has_child = gtk_tree_model_iter_has_child(model, b);
gchar *a_string;
gchar *b_string;
gint cmp_res;
if (a_has_child != b_has_child)
return a_has_child ? -1 : 1;
gtk_tree_model_get(model, a, 1, &a_string, -1);
gtk_tree_model_get(model, b, 1, &b_string, -1);
cmp_res = strcmp(a_string, b_string);
g_free(a_string);
g_free(b_string);
return cmp_res;
}
GtkTreeStore *encodings_encoding_store_new(gboolean has_detect)
{
GtkTreeStore *store;
GtkTreeIter iter_current, iter_westeuro, iter_easteuro, iter_eastasian,
iter_asian, iter_utf8, iter_middleeast;
GtkTreeIter *iter_parent;
gchar *encoding_string;
gint i;
store = gtk_tree_store_new(2, G_TYPE_INT, G_TYPE_STRING);
if (has_detect)
{
gtk_tree_store_append(store, &iter_current, NULL);
gtk_tree_store_set(store, &iter_current, 0, GEANY_ENCODINGS_MAX, 1, _("Detect from file"), -1);
}
gtk_tree_store_append(store, &iter_westeuro, NULL);
gtk_tree_store_set(store, &iter_westeuro, 0, -1, 1, _("West European"), -1);
gtk_tree_store_append(store, &iter_easteuro, NULL);
gtk_tree_store_set(store, &iter_easteuro, 0, -1, 1, _("East European"), -1);
gtk_tree_store_append(store, &iter_eastasian, NULL);
gtk_tree_store_set(store, &iter_eastasian, 0, -1, 1, _("East Asian"), -1);
gtk_tree_store_append(store, &iter_asian, NULL);
gtk_tree_store_set(store, &iter_asian, 0, -1, 1, _("SE & SW Asian"), -1);
gtk_tree_store_append(store, &iter_middleeast, NULL);
gtk_tree_store_set(store, &iter_middleeast, 0, -1, 1, _("Middle Eastern"), -1);
gtk_tree_store_append(store, &iter_utf8, NULL);
gtk_tree_store_set(store, &iter_utf8, 0, -1, 1, _("Unicode"), -1);
for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
{
switch (encodings[i].group)
{
case WESTEUROPEAN: iter_parent = &iter_westeuro; break;
case EASTEUROPEAN: iter_parent = &iter_easteuro; break;
case EASTASIAN: iter_parent = &iter_eastasian; break;
case ASIAN: iter_parent = &iter_asian; break;
case MIDDLEEASTERN: iter_parent = &iter_middleeast; break;
case UNICODE: iter_parent = &iter_utf8; break;
case NONE:
default: iter_parent = NULL;
}
gtk_tree_store_append(store, &iter_current, iter_parent);
encoding_string = encodings_to_string(&encodings[i]);
gtk_tree_store_set(store, &iter_current, 0, i, 1, encoding_string, -1);
g_free(encoding_string);
}
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 1, GTK_SORT_ASCENDING);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), 1, encoding_combo_store_sort_func, NULL, NULL);
return store;
}
gint encodings_encoding_store_get_encoding(GtkTreeStore *store, GtkTreeIter *iter)
{
gint enc;
gtk_tree_model_get(GTK_TREE_MODEL(store), iter, 0, &enc, -1);
return enc;
}
gboolean encodings_encoding_store_get_iter(GtkTreeStore *store, GtkTreeIter *iter, gint enc)
{
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), iter))
{
do
{
if (encodings_encoding_store_get_encoding(store, iter) == enc)
return TRUE;
}
while (ui_tree_model_iter_any_next(GTK_TREE_MODEL(store), iter, TRUE));
}
return FALSE;
}
void encodings_encoding_store_cell_data_func(GtkCellLayout *cell_layout,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data)
{
gboolean sensitive = !gtk_tree_model_iter_has_child(tree_model, iter);
gchar *text;
gtk_tree_model_get(tree_model, iter, 1, &text, -1);
g_object_set(cell, "sensitive", sensitive, "text", text, NULL);
g_free(text);
}
/**
* Tries to convert @a buffer into UTF-8 encoding from the encoding specified with @a charset.
* If @a fast is not set, additional checks to validate the converted string are performed.

View File

@ -80,6 +80,15 @@ void encodings_select_radio_item(const gchar *charset);
void encodings_init(void);
void encodings_finalize(void);
GtkTreeStore *encodings_encoding_store_new(gboolean has_detect);
gint encodings_encoding_store_get_encoding(GtkTreeStore *store, GtkTreeIter *iter);
gboolean encodings_encoding_store_get_iter(GtkTreeStore *store, GtkTreeIter *iter, gint enc);
void encodings_encoding_store_cell_data_func(GtkCellLayout *cell_layout, GtkCellRenderer *cell,
GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data);
gchar *encodings_convert_to_utf8(const gchar *buffer, gssize size, gchar **used_encoding);
/* Converts a string from the given charset to UTF-8.

View File

@ -547,8 +547,7 @@ static void prefs_init_dialog(void)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.tab_order_beside);
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
/* luckily the index of the combo box items match the index of the encodings array */
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding);
ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding);
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
@ -558,10 +557,10 @@ static void prefs_init_dialog(void)
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
if (file_prefs.default_open_encoding >= 0)
{
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding);
ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding);
}
else
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8);
ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8);
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
if (file_prefs.default_eol_character >= 0 && file_prefs.default_eol_character < 3)
@ -1020,13 +1019,13 @@ on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
file_prefs.tab_order_beside = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
file_prefs.default_new_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
file_prefs.default_new_encoding = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(widget));
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
{
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
file_prefs.default_open_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
file_prefs.default_open_encoding = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(widget));
}
else
file_prefs.default_open_encoding = -1;
@ -1663,22 +1662,34 @@ void prefs_show_dialog(void)
{
if (ui_widgets.prefs_dialog == NULL)
{
GtkListStore *encoding_list, *eol_list;
GtkWidget *label, *widget;
guint i;
gchar *encoding_string;
GtkListStore *eol_list;
GtkWidget *label;
ui_widgets.prefs_dialog = create_prefs_dialog();
gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog");
gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window));
/* init the file encoding combo boxes */
encoding_list = ui_builder_get_object("encoding_list");
for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
{
encoding_string = encodings_to_string(&encodings[i]);
list_store_append_text(encoding_list, encoding_string);
g_free(encoding_string);
struct {
const gchar *combo, *renderer;
} names[] = {
{ "combo_new_encoding", "combo_new_encoding_renderer" },
{ "combo_open_encoding", "combo_open_encoding_renderer" }
};
guint i;
GtkTreeStore *encoding_list = encodings_encoding_store_new(FALSE);
for (i = 0; i < G_N_ELEMENTS(names); i++)
{
GtkWidget *combo = ui_lookup_widget(ui_widgets.prefs_dialog, names[i].combo);
gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo),
ui_builder_get_object(names[i].renderer),
encodings_encoding_store_cell_data_func, NULL, NULL);
gtk_combo_box_set_model(GTK_COMBO_BOX(combo), GTK_TREE_MODEL(encoding_list));
}
g_object_unref(encoding_list);
}
/* init the eol character combo box */
@ -1687,12 +1698,6 @@ void prefs_show_dialog(void)
list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CR));
list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_LF));
/* wet combo box wrap width after having filled the encoding to workaround
* GTK bug https://bugzilla.gnome.org/show_bug.cgi?id=722388 */
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(widget), 3);
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(widget), 3);
/* add manually GeanyWrapLabels because they can't be added with Glade */
/* page Tools */

View File

@ -853,8 +853,6 @@ static void create_fif_dialog(void)
*check_recursive, *check_extra, *entry_extra, *check_regexp, *combo_files_mode;
GtkWidget *dbox, *sbox, *lbox, *rbox, *hbox, *vbox, *ebox;
GtkSizeGroup *size_group;
gchar *encoding_string;
guint i;
fif_dlg.dialog = gtk_dialog_new_with_buttons(
_("Find in Files"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT,
@ -931,14 +929,7 @@ 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_text_new();
for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
{
encoding_string = encodings_to_string(&encodings[i]);
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);
e_combo = ui_create_encodings_combo_box(FALSE, GEANY_ENCODING_UTF_8);
gtk_label_set_mnemonic_widget(GTK_LABEL(label2), e_combo);
fif_dlg.encoding_combo = e_combo;
@ -1118,7 +1109,7 @@ void search_show_find_in_files_dialog_full(const gchar *text, const gchar *dir)
/* set the encoding of the current file */
if (doc != NULL)
enc_idx = encodings_get_idx_from_charset(doc->encoding);
gtk_combo_box_set_active(GTK_COMBO_BOX(fif_dlg.encoding_combo), enc_idx);
ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(fif_dlg.encoding_combo), enc_idx);
/* put the focus to the directory entry if it is empty */
if (utils_str_equal(gtk_entry_get_text(GTK_ENTRY(entry)), ""))
@ -1600,8 +1591,8 @@ on_find_in_files_dialog_response(GtkDialog *dialog, gint response,
GtkWidget *dir_combo = fif_dlg.dir_combo;
const gchar *utf8_dir =
gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(dir_combo))));
GeanyEncodingIndex enc_idx = gtk_combo_box_get_active(
GTK_COMBO_BOX(fif_dlg.encoding_combo));
GeanyEncodingIndex enc_idx =
ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(fif_dlg.encoding_combo));
if (G_UNLIKELY(EMPTY(utf8_dir)))
ui_set_statusbar(FALSE, _("Invalid directory for find in files."));

View File

@ -570,45 +570,6 @@ static GdkPixbuf *get_tag_icon(const gchar *icon_name)
}
/* finds the next iter at any level
* @param iter in/out, the current iter, will be changed to the next one
* @param down whether to try the child iter
* @return TRUE if there @p iter was set, or FALSE if there is no next iter */
static gboolean next_iter(GtkTreeModel *model, GtkTreeIter *iter, gboolean down)
{
GtkTreeIter guess;
GtkTreeIter copy = *iter;
/* go down if the item has children */
if (down && gtk_tree_model_iter_children(model, &guess, iter))
*iter = guess;
/* or to the next item at the same level */
else if (gtk_tree_model_iter_next(model, &copy))
*iter = copy;
/* or to the next item at a parent level */
else if (gtk_tree_model_iter_parent(model, &guess, iter))
{
copy = guess;
while(TRUE)
{
if (gtk_tree_model_iter_next(model, &copy))
{
*iter = copy;
return TRUE;
}
else if (gtk_tree_model_iter_parent(model, &copy, &guess))
guess = copy;
else
return FALSE;
}
}
else
return FALSE;
return TRUE;
}
static gboolean find_toplevel_iter(GtkTreeStore *store, GtkTreeIter *iter, const gchar *title)
{
GtkTreeModel *model = GTK_TREE_MODEL(store);
@ -1314,7 +1275,7 @@ static gboolean tree_store_remove_row(GtkTreeStore *store, GtkTreeIter *iter)
if (! cont && has_parent)
{
*iter = parent;
cont = next_iter(GTK_TREE_MODEL(store), iter, FALSE);
cont = ui_tree_model_iter_any_next(GTK_TREE_MODEL(store), iter, FALSE);
}
return cont;
@ -1494,7 +1455,7 @@ static void update_tree_tags(GeanyDocument *doc, GList **tags)
gtk_tree_model_get(model, &iter, SYMBOLS_COLUMN_TAG, &tag, -1);
if (! tag) /* most probably a toplevel, skip it */
cont = next_iter(model, &iter, TRUE);
cont = ui_tree_model_iter_any_next(model, &iter, TRUE);
else
{
GList *found_item;
@ -1527,7 +1488,7 @@ static void update_tree_tags(GeanyDocument *doc, GList **tags)
tags_table_remove(tags_table, found);
*tags = g_list_delete_link(*tags, found_item);
cont = next_iter(model, &iter, TRUE);
cont = ui_tree_model_iter_any_next(model, &iter, TRUE);
}
tm_tag_unref(tag);

View File

@ -2807,3 +2807,94 @@ const gchar *ui_lookup_stock_label(const gchar *stock_id)
g_warning("No stock id '%s'!", stock_id);
return NULL;
}
/* finds the next iter at any level
* @param iter in/out, the current iter, will be changed to the next one
* @param down whether to try the child iter
* @return TRUE if there @p iter was set, or FALSE if there is no next iter */
gboolean ui_tree_model_iter_any_next(GtkTreeModel *model, GtkTreeIter *iter, gboolean down)
{
GtkTreeIter guess;
GtkTreeIter copy = *iter;
/* go down if the item has children */
if (down && gtk_tree_model_iter_children(model, &guess, iter))
*iter = guess;
/* or to the next item at the same level */
else if (gtk_tree_model_iter_next(model, &copy))
*iter = copy;
/* or to the next item at a parent level */
else if (gtk_tree_model_iter_parent(model, &guess, iter))
{
copy = guess;
while (TRUE)
{
if (gtk_tree_model_iter_next(model, &copy))
{
*iter = copy;
return TRUE;
}
else if (gtk_tree_model_iter_parent(model, &copy, &guess))
guess = copy;
else
return FALSE;
}
}
else
return FALSE;
return TRUE;
}
GtkWidget *ui_create_encodings_combo_box(gboolean has_detect, gint default_enc)
{
GtkCellRenderer *renderer;
GtkTreeIter iter;
GtkWidget *combo = gtk_combo_box_new();
GtkTreeStore *store = encodings_encoding_store_new(has_detect);
if (default_enc < 0 || default_enc >= GEANY_ENCODINGS_MAX)
default_enc = has_detect ? GEANY_ENCODINGS_MAX : GEANY_ENCODING_NONE;
gtk_combo_box_set_model(GTK_COMBO_BOX(combo), GTK_TREE_MODEL(store));
if (encodings_encoding_store_get_iter(store, &iter, default_enc))
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter);
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo), renderer,
encodings_encoding_store_cell_data_func, NULL, NULL);
return combo;
}
gint ui_encodings_combo_box_get_active_encoding(GtkComboBox *combo)
{
GtkTreeIter iter;
gint enc = GEANY_ENCODING_NONE;
/* there should always be an active iter anyway, but we check just in case */
if (gtk_combo_box_get_active_iter(combo, &iter))
{
GtkTreeModel *model = gtk_combo_box_get_model(combo);
enc = encodings_encoding_store_get_encoding(GTK_TREE_STORE(model), &iter);
}
return enc;
}
gboolean ui_encodings_combo_box_set_active_encoding(GtkComboBox *combo, gint enc)
{
GtkTreeIter iter;
GtkTreeModel *model = gtk_combo_box_get_model(combo);
if (encodings_encoding_store_get_iter(GTK_TREE_STORE(model), &iter, enc))
{
gtk_combo_box_set_active_iter(combo, &iter);
return TRUE;
}
return FALSE;
}

View File

@ -318,6 +318,7 @@ gboolean ui_tree_view_find_next(GtkTreeView *treeview, TVMatchCallback cb);
gboolean ui_tree_view_find_previous(GtkTreeView *treeview, TVMatchCallback cb);
gboolean ui_tree_model_iter_any_next(GtkTreeModel *model, GtkTreeIter *iter, gboolean down);
void ui_statusbar_showhide(gboolean state);
@ -341,6 +342,12 @@ GIcon *ui_get_mime_icon(const gchar *mime_type);
void ui_focus_current_document(void);
GtkWidget *ui_create_encodings_combo_box(gboolean has_detect, gint default_enc);
gint ui_encodings_combo_box_get_active_encoding(GtkComboBox *combo);
gboolean ui_encodings_combo_box_set_active_encoding(GtkComboBox *combo, gint enc);
G_END_DECLS
#endif