88#define TYPE_COMBO_BOX_ENTRY get_combo_box_entry_type()
91 static volatile gsize type = 0;
92 if (g_once_init_enter(&type))
94 GType g_type = g_type_register_static_simple(GTK_TYPE_COMBO_BOX,
"dummy-combo-box-entry",
95 sizeof(GtkComboBoxClass),
NULL,
sizeof(GtkComboBox),
NULL, G_TYPE_FLAG_ABSTRACT);
96 g_once_init_leave(&type, g_type);
155 gboolean *setting = se->
setting;
191 gchararray *setting = se->
setting;
202 *setting ? *setting :
"");
211 gchararray **setting = se->
setting;
216 g_strfreev(*setting);
219 if (*setting ==
NULL)
227 const gchar **strv = *setting ? (
const gchar **)*setting :
dummy;
230 strv, g_strv_length((gchar **)strv));
249 switch (
entry->setting_type)
259 if (
entry->setting_type == G_TYPE_STRV)
262 g_warning(
"Unhandled type for %s::%s in %s()!",
group->
name,
entry->key_name,
306 keyfile = g_key_file_new();
307 ret = g_key_file_load_from_file(keyfile,
filename, 0,
NULL);
311 g_key_file_free(keyfile);
333 keyfile = g_key_file_new();
336 g_key_file_load_from_file(keyfile,
filename, flags,
NULL);
339 data = g_key_file_to_data(keyfile,
NULL,
NULL);
342 g_key_file_free(keyfile);
384 if (
entry->setting_type == G_TYPE_STRING)
385 g_free(*(gchararray *)
entry->setting);
386 else if (
entry->setting_type == G_TYPE_STRV)
387 g_strfreev(*(gchararray **)
entry->setting);
448 const gchar *key_name, gpointer default_value)
450 StashPref init = {type, setting, key_name, default_value, G_TYPE_NONE,
NULL, {
NULL}};
456 if (type == G_TYPE_STRING ||
459 *(gpointer**)setting =
NULL;
473 const gchar *key_name, gboolean default_value)
475 add_pref(
group, G_TYPE_BOOLEAN, setting, key_name, GINT_TO_POINTER(default_value));
486 const gchar *key_name, gint default_value)
488 add_pref(
group, G_TYPE_INT, setting, key_name, GINT_TO_POINTER(default_value));
500 const gchar *key_name,
const gchar *default_value)
502 add_pref(
group, G_TYPE_STRING, setting, key_name, (gpointer)default_value);
514 const gchar *key_name,
const gchar **default_value)
516 add_pref(
group, G_TYPE_STRV, setting, key_name, (gpointer)default_value);
528 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *setting);
531 *setting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
540 gint *setting =
entry->setting;
542 g_assert(
entry->setting_type == G_TYPE_INT);
547 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), *setting);
551 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
552 *setting = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
561 gint *setting =
entry->setting;
566 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), *setting);
569 *setting = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
578 gchararray *setting =
entry->setting;
583 gtk_entry_set_text(GTK_ENTRY(widget), *setting);
587 *setting = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
596 widget = gtk_bin_get_child(GTK_BIN(widget));
605 GtkWidget *parent, *found_widget;
607 g_return_val_if_fail(widget !=
NULL,
NULL);
608 g_return_val_if_fail(widget_name !=
NULL,
NULL);
612 if (GTK_IS_MENU(widget))
613 parent = gtk_menu_get_attach_widget(GTK_MENU(widget));
615 parent = gtk_widget_get_parent(widget);
617 parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget),
"GladeParentKey");
623 found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name);
624 if (G_UNLIKELY(found_widget ==
NULL))
625 g_warning(
"Widget not found: %s", widget_name);
638 widget = (GtkWidget *)widget_id;
640 if (!GTK_IS_WIDGET(widget))
642 g_warning(
"Unknown widget in %s()!", G_STRFUNC);
655 if (*setting == enum_id)
656 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
659 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
671 GtkWidget *widget =
NULL;
683 if (!
field->widget_id)
686 if (g_slist_length(gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget))) !=
count)
687 g_warning(
"Missing/invalid radio button widget IDs found!");
694 GObject *
object = G_OBJECT(widget);
695 const gchar *
name =
entry->extra.property_name;
700 if (
entry->setting_type == G_TYPE_BOOLEAN)
701 g_object_set(
object,
name, *(gboolean*)
entry->setting,
NULL);
702 else if (
entry->setting_type == G_TYPE_INT)
704 else if (
entry->setting_type == G_TYPE_STRING)
705 g_object_set(
object,
name, *(gchararray*)
entry->setting,
NULL);
706 else if (
entry->setting_type == G_TYPE_STRV)
707 g_object_set(
object,
name, *(gchararray**)
entry->setting,
NULL);
710 g_warning(
"Unhandled type %s for %s in %s()!", g_type_name(
entry->setting_type),
711 entry->key_name, G_STRFUNC);
715 if (
entry->setting_type == G_TYPE_STRING)
716 g_free(*(gchararray*)
entry->setting);
717 else if (
entry->setting_type == G_TYPE_STRV)
718 g_strfreev(*(gchararray**)
entry->setting);
736 if (
entry->widget_type == G_TYPE_NONE)
740 if (
entry->widget_type == GTK_TYPE_RADIO_BUTTON)
749 g_warning(
"Unknown widget for %s::%s in %s()!",
group->
name,
entry->key_name,
755 if (
entry->widget_type == GTK_TYPE_TOGGLE_BUTTON)
757 else if (
entry->widget_type == GTK_TYPE_SPIN_BUTTON)
759 else if (
entry->widget_type == GTK_TYPE_COMBO_BOX)
763 else if (
entry->widget_type == GTK_TYPE_ENTRY)
765 else if (
entry->widget_type == G_TYPE_PARAM)
768 g_warning(
"Unhandled type for %s::%s in %s()!",
group->
name,
entry->key_name,
802 const gchar *key_name, gpointer default_value,
806 add_pref(
group, setting_type, setting, key_name, default_value);
808 entry->widget_type = widget_type;
809 entry->widget_id = widget_id;
823 const gchar *key_name, gboolean default_value,
StashWidgetID widget_id)
826 GTK_TYPE_TOGGLE_BUTTON, widget_id);
846 const gchar *key_name, gint default_value,
851 GTK_TYPE_RADIO_BUTTON,
NULL);
857 va_start(args, enum_id);
860 if (!va_arg(args, gpointer))
868 entry->extra.radio_buttons = array;
870 va_start(args, enum_id);
881 item->
widget_id = va_arg(args, gpointer);
882 item->
enum_id = va_arg(args, gint);
897 const gchar *key_name, gint default_value,
StashWidgetID widget_id)
900 GTK_TYPE_SPIN_BUTTON, widget_id);
913 const gchar *key_name, gint default_value,
StashWidgetID widget_id)
916 GTK_TYPE_COMBO_BOX, widget_id);
930 const gchar *key_name,
const gchar *default_value,
StashWidgetID widget_id)
945 const gchar *key_name,
const gchar *default_value,
StashWidgetID widget_id)
948 GTK_TYPE_ENTRY, widget_id);
954 GObjectClass *klass = G_OBJECT_GET_CLASS(
object);
957 ps = g_object_class_find_property(klass, property_name);
958 return ps->value_type;
978 const gchar *key_name, gpointer default_value,
StashWidgetID widget_id,
979 const gchar *property_name, GType type)
1012 GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
1014 GType cell_type = GPOINTER_TO_SIZE(user_data);
1017 gboolean matches_type;
1022 g_object_set(cell,
"visible", matches_type,
"sensitive", matches_type,
1023 cell_type == G_TYPE_BOOLEAN ?
"activatable" :
"editable", matches_type,
NULL);
1029 case G_TYPE_BOOLEAN:
1035 g_object_set(cell,
"text",
text,
NULL);
1054 path = gtk_tree_path_new_from_string(path_str);
1055 gtk_tree_model_get_iter(model, &iter, path);
1061 case G_TYPE_BOOLEAN:
1072 gtk_tree_model_row_changed(model, path, &iter);
1073 gtk_tree_path_free(path);
1078 GtkTreeModel *model)
1085 GtkTreeModel *model)
1092 GtkTreeIter *iter, gpointer user_data)
1107 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
1124 gtk_list_store_append(store, &iter);
1156 GtkListStore *store;
1157 GtkTreeModel *model;
1158 GtkCellRenderer *cell;
1159 GtkTreeViewColumn *column;
1160 GtkAdjustment *adjustment;
1162 store = gtk_list_store_new(
STASH_TREE_COUNT, G_TYPE_STRING, G_TYPE_POINTER);
1164 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),
STASH_TREE_NAME,
1165 GTK_SORT_ASCENDING);
1167 model = GTK_TREE_MODEL(store);
1168 gtk_tree_view_set_model(tree, model);
1169 g_object_unref(G_OBJECT(store));
1172 cell = gtk_cell_renderer_text_new();
1173 column = gtk_tree_view_column_new_with_attributes(
_(
"Name"), cell,
"text",
1176 gtk_tree_view_column_set_sort_indicator(column, TRUE);
1177 gtk_tree_view_append_column(tree, column);
1179 column = gtk_tree_view_column_new();
1180 gtk_tree_view_column_set_title(column,
_(
"Value"));
1181 gtk_tree_view_append_column(tree, column);
1183 cell = gtk_cell_renderer_toggle_new();
1185 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), cell, FALSE);
1186 gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(column), cell,
1189 cell = gtk_cell_renderer_text_new();
1190 g_object_set(cell,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
1192 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), cell, TRUE);
1193 gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(column), cell,
1196 cell = gtk_cell_renderer_spin_new();
1197 adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0, G_MININT, G_MAXINT, 1, 10, 0));
1198 g_object_set(cell,
"adjustment", adjustment,
NULL);
1200 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), cell, FALSE);
1201 gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(column), cell,
1208 switch (
entry->setting_type)
1210 case G_TYPE_BOOLEAN:
1220 g_warning(
"Unhandled type for %s::%s in %s()!", value->
group_name,
1221 entry->key_name, G_STRFUNC);
1228 switch (
entry->setting_type)
1230 case G_TYPE_BOOLEAN:
1243 g_warning(
"Unhandled type for %s::%s in %s()!", value->
group_name,
1244 entry->key_name, G_STRFUNC);
1252 gboolean valid = gtk_tree_model_get_iter_first(model, &iter);
1268 valid = gtk_tree_model_iter_next(model, &iter);
void stash_group_add_combo_box_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id)
Adds a GtkComboBoxEntry widget pref.
static void stash_tree_append_prefs(GPtrArray *group_array, GtkListStore *store, PrefAction action)
static void handle_entry(GtkWidget *widget, StashPref *entry, PrefAction action)
void stash_group_free_settings(StashGroup *group)
Frees the memory allocated for setting values in a group.
void stash_group_add_spin_button_integer(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id)
Adds a GtkSpinButton widget pref.
static void stash_tree_renderer_edited(gchar *path_str, gchar *new_text, GtkTreeModel *model)
static void stash_tree_destroy_cb(GtkWidget *widget, gpointer user_data)
static void stash_tree_boolean_toggled(GtkCellRendererToggle *cell, gchar *path_str, GtkTreeModel *model)
static void handle_integer_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action)
static gboolean stash_tree_discard_value(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
void stash_group_add_radio_buttons(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id, gint enum_id,...)
Adds a GtkRadioButton widget group pref.
void stash_group_add_string(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value)
Adds string setting.
void stash_group_add_toggle_button(StashGroup *group, gboolean *setting, const gchar *key_name, gboolean default_value, StashWidgetID widget_id)
Adds a GtkToggleButton (or GtkCheckButton) widget pref.
static void handle_combo_box_entry(GtkWidget *widget, StashPref *entry, PrefAction action)
void stash_group_display(StashGroup *group, GtkWidget *owner)
Applies Stash settings to widgets, usually called before displaying the widgets.
void stash_group_save_to_key_file(StashGroup *group, GKeyFile *keyfile)
Writes group settings into key values in keyfile.
gint stash_group_save_to_file(StashGroup *group, const gchar *filename, GKeyFileFlags flags)
Writes group settings to a configuration file using GKeyFile.
static void keyfile_action(SettingAction action, StashGroup *group, GKeyFile *keyfile)
#define TYPE_COMBO_BOX_ENTRY
static void handle_radio_button(GtkWidget *widget, gint enum_id, gboolean *setting, PrefAction action)
static void stash_tree_string_edited(GtkCellRenderer *cell, gchar *path_str, gchar *new_text, GtkTreeModel *model)
void stash_tree_setup(GPtrArray *group_array, GtkTreeView *tree)
static StashPref * add_pref(StashGroup *group, GType type, gpointer setting, const gchar *key_name, gpointer default_value)
GType stash_group_get_type(void)
Gets the GBoxed-derived GType for StashGroup.
static void stash_tree_update_pref(StashTreeValue *value, StashPref *entry)
void stash_group_add_integer(StashGroup *group, gint *setting, const gchar *key_name, gint default_value)
Adds integer setting.
void stash_group_add_string_vector(StashGroup *group, gchar ***setting, const gchar *key_name, const gchar **default_value)
Adds string vector setting (array of strings).
static void handle_radio_buttons(GtkWidget *owner, StashPref *entry, PrefAction action)
gboolean stash_group_load_from_file(StashGroup *group, const gchar *filename)
Reads group settings from a configuration file using GKeyFile.
struct EnumWidget EnumWidget
static void handle_toggle_button(GtkWidget *widget, gboolean *setting, PrefAction action)
static StashPref * add_widget_pref(StashGroup *group, GType setting_type, gpointer setting, const gchar *key_name, gpointer default_value, GType widget_type, StashWidgetID widget_id)
static void handle_spin_button(GtkWidget *widget, StashPref *entry, PrefAction action)
static void handle_combo_box(GtkWidget *widget, StashPref *entry, PrefAction action)
void stash_group_load_from_key_file(StashGroup *group, GKeyFile *keyfile)
Reads key values from keyfile into the group settings.
static void handle_widget_property(GtkWidget *widget, StashPref *entry, PrefAction action)
static void free_stash_pref(StashPref *pref)
static void handle_boolean_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action)
static GType get_combo_box_entry_type(void)
void stash_group_update(StashGroup *group, GtkWidget *owner)
Applies widget values to Stash settings, usually called after displaying the widgets.
void stash_group_add_combo_box(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id)
Adds a GtkComboBox widget pref.
static GtkWidget * get_widget(GtkWidget *owner, StashWidgetID widget_id)
static GType object_get_property_type(GObject *object, const gchar *property_name)
void stash_tree_update(GtkTreeView *tree)
void stash_group_set_use_defaults(StashGroup *group, gboolean use_defaults)
void stash_group_add_boolean(StashGroup *group, gboolean *setting, const gchar *key_name, gboolean default_value)
Adds boolean setting.
StashGroup * stash_group_new(const gchar *name)
Creates a new group.
static void stash_tree_renderer_set_data(GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
void stash_tree_display(GtkTreeView *tree)
void stash_group_add_widget_property(StashGroup *group, gpointer setting, const gchar *key_name, gpointer default_value, StashWidgetID widget_id, const gchar *property_name, GType type)
Adds a widget's read/write property to the stash group.
G_DEFINE_BOXED_TYPE(StashGroup, stash_group, stash_group_dup, stash_group_free)
void stash_group_free(StashGroup *group)
Frees a group.
void stash_group_set_various(StashGroup *group, gboolean various, const gchar *prefix)
static void stash_tree_action(GtkTreeModel *model, PrefAction action)
static void handle_strv_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action)
static void pref_action(PrefAction action, StashGroup *group, GtkWidget *owner)
static StashGroup * stash_group_dup(StashGroup *src)
static void stash_tree_display_pref(StashTreeValue *value, StashPref *entry)
void stash_group_add_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id)
Adds a GtkEntry widget pref.
static GtkWidget * lookup_widget(GtkWidget *widget, const gchar *widget_name)
static void handle_string_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action)
static void stash_tree_append_pref(StashGroup *group, StashPref *entry, GtkListStore *store, PrefAction action)
Lightweight library for reading/writing GKeyFile settings and synchronizing widgets with C variables.
gconstpointer StashWidgetID
Can be GtkWidget* or gchar* depending on whether the owner argument is used for stash_group_display()...
struct EnumWidget * radio_buttons
union StashPref::@117 extra
const gchar * property_name
struct StashTreeValue::@118 data
Defines internationalization macros.
gint utils_write_file(const gchar *filename, const gchar *text)
Writes text into a file named filename.
gint utils_get_setting_integer(GKeyFile *config, const gchar *section, const gchar *key, const gint default_value)
Wraps g_key_file_get_integer() to add a default value argument.
gboolean utils_get_setting_boolean(GKeyFile *config, const gchar *section, const gchar *key, const gboolean default_value)
Wraps g_key_file_get_boolean() to add a default value argument.
gchar * utils_get_setting_string(GKeyFile *config, const gchar *section, const gchar *key, const gchar *default_value)
Wraps g_key_file_get_string() to add a default value argument.
General utility functions, non-GTK related.
#define foreach_ptr_array(item, idx, ptr_array)
Iterates all the pointers in ptr_array.
#define foreach_c_array(item, array, len)
Iterates all the items in array using pointers.
#define SETPTR(ptr, result)
Assigns result to ptr, then frees the old value.