#include "libublsettings-gtk3.h" dictionary *yon_gtk_tree_store_get_children(GtkTreeStore *tree, GtkTreeIter *parent,int column){ g_return_val_if_fail(GTK_IS_TREE_STORE(tree),NULL); dictionary *children = NULL; GtkTreeIter iter; if(gtk_tree_model_iter_has_child){ gtk_tree_model_iter_children(GTK_TREE_MODEL(tree),&iter,parent); int valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(tree),&iter); for (;valid;valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(tree),&iter)){ void *result = NULL; gtk_tree_model_get(GTK_TREE_MODEL(tree),&iter,column,&result,-1); dictionary *child_children = yon_gtk_tree_store_get_children(tree,&iter,column); yon_dictionary_add_or_create_if_exists_with_data(children,result,child_children); } return children; } return NULL; } void yon_gtk_tree_store_fill_children(GtkTreeStore *tree, GtkTreeIter *parent, dictionary *data, int column){ GtkTreeIter iter; dictionary *dict=NULL; for_dictionaries(dict,data){ gtk_tree_store_append(tree,&iter,parent); gtk_tree_store_set(tree,&iter,column,data->key,-1); if (data->data){ yon_gtk_tree_store_fill_children(tree,&iter,data->data,column); } } } void yon_on_password_visibility_changed(GtkEntry *self, GtkEntryIconPosition position){ if (position==GTK_ENTRY_ICON_SECONDARY){ int status = gtk_entry_get_visibility(self); gtk_entry_set_visibility(self,!status); } } void yon_gtk_entry_set_password_visibility_icon(GtkEntry *target){ g_return_if_fail(GTK_IS_ENTRY(target)); gtk_entry_set_icon_from_icon_name(target,GTK_ENTRY_ICON_SECONDARY,"com.ublinux.libublsettingsui-gtk3.view-symbolic"); g_signal_connect(G_OBJECT(target),"icon-release",G_CALLBACK(yon_on_password_visibility_changed),NULL); } void yon_gtk_tree_store_copy_recursive(GtkTreeModel *sourceModel, GtkTreeIter *sourceIter, GtkTreeStore *destination, GtkTreeIter *parentIter) { GtkTreeIter destIter; gtk_tree_store_append(destination, &destIter, parentIter); gint nColumns = gtk_tree_model_get_n_columns(sourceModel); for (gint col = 0; col < nColumns; col++) { GValue value = G_VALUE_INIT; gtk_tree_model_get_value(sourceModel, sourceIter, col, &value); gtk_tree_store_set_value(destination, &destIter, col, &value); g_value_unset(&value); } if (gtk_tree_model_iter_has_child(sourceModel, sourceIter)) { GtkTreeIter childIter; gboolean validChild = gtk_tree_model_iter_children(sourceModel, &childIter, sourceIter); while (validChild) { yon_gtk_tree_store_copy_recursive(sourceModel, &childIter, destination, &destIter); validChild = gtk_tree_model_iter_next(sourceModel, &childIter); } } } void yon_gtk_tree_store_copy_full(GtkTreeStore *source, GtkTreeStore *destination) { GtkTreeModel *sourceModel = GTK_TREE_MODEL(source); GtkTreeIter iter; gboolean valid; valid = gtk_tree_model_get_iter_first(sourceModel, &iter); while (valid) { yon_gtk_tree_store_copy_recursive(sourceModel, &iter, destination, NULL); valid = gtk_tree_model_iter_next(sourceModel, &iter); } } gboolean yon_gtk_tree_iter_get_from_combo_box_id(GtkComboBox *combo, GtkTreeModel *model, GtkTreeIter *iter){ g_return_val_if_fail(GTK_IS_COMBO_BOX(combo),0); g_return_val_if_fail(GTK_IS_TREE_MODEL(model),0); const char *id = gtk_combo_box_get_active_id(combo); if (yon_char_is_empty(id)) return 0; gtk_tree_model_get_iter_from_string(model,iter,id); return 1; } gboolean yon_gtk_tree_model_check_exist(GtkTreeModel *model, GtkTreeIter *iter, char *id, int column){ g_return_val_if_fail(model&>K_IS_TREE_MODEL(model),0); g_return_val_if_fail(iter,0); for_iter(model,iter){ char *check_target; gtk_tree_model_get(model,iter,column,&check_target,-1); if (!yon_char_is_empty(check_target)&&!strcmp(id,check_target)){ return 1; } } return 0; } gboolean yon_gtk_list_store_copy_full(GtkListStore *target, GtkListStore *source){ gtk_list_store_clear(target); GtkTreeIter iter, itar; g_return_val_if_fail(GTK_IS_LIST_STORE(target),0); g_return_val_if_fail(GTK_IS_LIST_STORE(source),0); int columns = gtk_tree_model_get_n_columns(GTK_TREE_MODEL(source)); int target_columns = gtk_tree_model_get_n_columns(GTK_TREE_MODEL(target)); if (columns!=target_columns){ g_log((gchar*)0,G_LOG_LEVEL_WARNING,"%s\n","Target and source models have different number of columns"); return 0; } for_iter(source,&iter){ gtk_list_store_append(target,&itar); for(int i=0;isize;i++){ g_signal_handlers_block_by_func(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(info->target),info->columns[i])),yon_on_fixed_changed,info); yon_gtk_tree_view_column_set_fixed_size(GTK_TREE_VIEW(info->target),info->columns[i]); g_signal_handlers_unblock_by_func(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(info->target),info->columns[i])),yon_on_fixed_changed,info); } } void on_row_fixed_deleted(GtkTreeModel* self, GtkTreePath* path, struct fixed_info *info){ for (int i=0;isize;i++){ g_signal_handlers_block_by_func(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(info->target),info->columns[i])),yon_on_fixed_changed,info); yon_gtk_tree_view_column_set_fixed_size(GTK_TREE_VIEW(info->target),info->columns[i]); g_signal_handlers_unblock_by_func(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(info->target),info->columns[i])),yon_on_fixed_changed,info); } } void yon_on_fixed_changed(GtkTreeViewColumn *self, GParamSpec*,struct fixed_info *info){ for (int i=0;isize;i++){ if (self == gtk_tree_view_get_column(GTK_TREE_VIEW(info->target),info->columns[i])){ int *new_columns = malloc(sizeof(int)*(info->size-1)); for (int j=0;jsize-1;j++){ if (jcolumns[j]; else new_columns[j]=info->columns[j+1]; } free(info->columns); info->columns=new_columns; info->size--; if (!info->size){ GObject *model = G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(info->target))); g_signal_handlers_disconnect_by_func(model,on_row_fixed_changed,info); g_signal_handlers_disconnect_by_func(model,on_row_fixed_deleted,info); free(info->columns); free(info); } g_signal_handlers_disconnect_by_func(self,yon_on_fixed_changed,info); return; } } } int yon_gtk_tree_view_set_fixed_size(GtkTreeView *target,...){ va_list args; va_start(args,target); int current; int target_columns = gtk_tree_view_get_n_columns(target); GtkTreeModel *model = gtk_tree_view_get_model(target); struct fixed_info *info = malloc(sizeof(struct fixed_info)); info->target=GTK_WIDGET(target); info->columns=NULL; info->size=0; g_signal_connect(G_OBJECT(model),"row-changed",G_CALLBACK(on_row_fixed_changed),info); g_signal_connect(G_OBJECT(model),"row-deleted",G_CALLBACK(on_row_fixed_deleted),info); while ((current=va_arg(args,int))!=-1){ if (current>target_columns) return 0; if (!info->columns) info->columns = malloc(sizeof(int)); else info->columns = realloc(info->columns,sizeof(int)*(info->size+1)); info->columns[info->size]=current; g_signal_connect(G_OBJECT(gtk_tree_view_get_column(target,current)),"notify::fixed-width",G_CALLBACK(yon_on_fixed_changed),info); info->size++; } va_end(args); return 1; }