#include "libublsettingsui-gtk3.h" #include "libublsettingsui-gtk3-save.h" /* ============== saving section ============== */ gboolean _yon_postsave_function_start(struct save_return *data){ save_success_function(data->save_success_argument,data->file_return,data->file_save); return G_SOURCE_REMOVE; } gboolean _yon_postsave_failure_function_start(struct save_return *data){ save_failure_function(data->save_success_argument,data->file_return,data->file_save); return G_SOURCE_REMOVE; } void _yon_saving_threaded(char *final_command){ FILE *file = popen(final_command,"r"); int file_save; config_str file_return = yon_config_load_file(file,&file_save); fclose(file); file_return = yon_char_parsed_append(file_return,&file_save,final_command); if (save_success_function) { struct save_return *data = malloc(sizeof(struct save_return)); data->save_success_argument = save_success_argument; data->file_return = file_return; data->file_save = file_save; gdk_threads_add_idle((GSourceFunc)_yon_postsave_function_start,data); } } struct loaded_config *yon_save_window_get_saved_parameters(template_saving_window *window){ int saved_size = 0; GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(window->ParametersTree)); int valid = gtk_tree_model_get_iter_first(model,&iter); config_str saved_parameters=NULL; for (;valid;valid = gtk_tree_model_iter_next(model,&iter)){ char *parameter, *value; int is_active; gtk_tree_model_get(model,&iter,0,&is_active,1,¶meter,3,&value,-1); if (is_active){ char *final_string = yon_char_unite(parameter,"=",value,NULL); yon_char_parsed_add_or_create_if_exists(saved_parameters,&saved_size,final_string); free(final_string); } } struct loaded_config *final = yon_config_convert_parameter(saved_parameters,saved_size); struct loaded_config *current = NULL; for_iter(model,&iter){ char *target, *section; gtk_tree_model_get(model,&iter,1,&target,7,§ion,-1); struct loaded_config *found = (struct loaded_config*)yon_dictionary_get((dictionary**)&final,target); if (found){ found->section=section; } } return final; } config_str yon_loaded_config_convert_to_save_command(struct loaded_config *target, int *size,char *path){ (*size)=0; config_str final_commands = NULL; { struct yon_temp_command_sections { dictionary_fields(yon_temp_command_sections); int status; }; struct yon_temp_command_sections *sections = NULL; struct loaded_config *current; for_dictionaries(current,target){ struct yon_temp_command_sections *cur_section=NULL, *found = NULL; if (sections){ for_dictionaries(cur_section,sections){ if (!strcmp(current->section,cur_section->key)){ int status = yon_config_get_status(current->key); if ((status==-1&&cur_section->status==-1)||(status>-1)&&cur_section->status>-1){ found = cur_section; } } } cur_section = found; } if (cur_section){ char *parameters_for_current_command = NULL; if (yon_config_get_status(current->key)==-1){ parameters_for_current_command = yon_char_unite((char*)cur_section->data," ", current->key,NULL); } else { parameters_for_current_command = yon_char_unite((char*)cur_section->data," ", current->key,"=\'",(char*)current->data,"\'",NULL); } free(current->data); cur_section->data = parameters_for_current_command; } else { char *parameters_for_current_command = NULL; if (yon_config_get_status(current->key)==-1){ parameters_for_current_command = current->key; } else { parameters_for_current_command = yon_char_unite(current->key,"=\'",(char*)current->data,"\'",NULL); } dictionary *sections_dict = NULL; if (sections) sections_dict = yon_dictionary_get_last((dictionary*)sections); sections = malloc(sizeof(struct yon_temp_command_sections)); sections->data=parameters_for_current_command; sections->first=sections; sections->key=yon_char_new(current->section); sections->next=NULL; sections->prev=NULL; sections->status=0; if (sections_dict){ sections_dict->next = (dictionary*)sections; sections->prev=(struct yon_temp_command_sections*)sections_dict; sections->first=(struct yon_temp_command_sections*)sections_dict->first; } // yon_dictionary_add_or_create_if_exists_with_data(sections_dict,current->section,parameters_for_current_command); sections->status=yon_config_get_status(current->key); } } config_str commands = NULL; { struct yon_temp_command_sections *current; for_dictionaries(current,sections){ char *dull_command = NULL; if (current->status>=0){ dull_command = ubconfig_set_command_full(path,current->key,(char*)current->data); } else { dull_command = ubconfig_remove_command_full(path,current->key,(char*)current->data); } yon_char_parsed_add_or_create_if_exists(commands,size,dull_command); free(dull_command); } } return commands; } } void yon_save_window_set_postsave_function(void *function, void *data){ save_success_function=function; save_success_argument=data; } void yon_save_window_set_postsave_failure_function(void *function, void *data){ save_failure_function=function; save_failure_argument=data; } /* ============== window section ============== */ void yon_save_window_set_status(template_saving_window *window,char *path,YON_CONFIG_TYPE type){ textdomain(template_ui_LocaleName); window->type=type; window->custom_save_path=path; if (type==YON_CONFIG_BOTH){ yon_ubl_status_box_spawn_infinite(GTK_CONTAINER(window->StatusBox),"savingTarget",SAVING_GLOBAL_LOCAL_STATE_LABEL,BACKGROUND_IMAGE_INFO_TYPE); } else if (type==YON_CONFIG_GLOBAL){ yon_ubl_status_box_spawn_infinite(GTK_CONTAINER(window->StatusBox),"savingTarget",SAVING_GLOBAL_STATE_LABEL,BACKGROUND_IMAGE_INFO_TYPE); } else if (type==YON_CONFIG_LOCAL){ yon_ubl_status_box_spawn_infinite(GTK_CONTAINER(window->StatusBox),"savingTarget",SAVING_LOCAL_STATE_LABEL,BACKGROUND_IMAGE_INFO_TYPE); } else if (type==YON_CONFIG_CUSTOM){ yon_ubl_status_box_spawn_infinite(GTK_CONTAINER(window->StatusBox),"savingTarget",SAVING_CUSTOM_STATE_LABEL(path),BACKGROUND_IMAGE_INFO_TYPE); } textdomain(template_app_information.app_locale); } gboolean yon_save_window_destroy_if_empty(template_saving_window *window){ GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(window->list),&iter)){ gtk_widget_destroy(window->Window); textdomain(template_ui_LocaleName); yon_ubl_status_box_render(NOTHING_TO_SAVE_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); textdomain(template_app_information.app_locale); if (save_failure_function){ struct save_return *data = malloc(sizeof(struct save_return)); data->save_success_argument = save_failure_argument; data->file_return = NULL; data->file_save = 0; gdk_threads_add_idle((GSourceFunc)_yon_postsave_failure_function_start,data); } return 0; } return 1; } void on_save_window_parameter_switched(GtkCellRendererToggle *self, gchar *path, template_saving_window *window){ GtkTreeIter iter,itar; if (path){ if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(window->list),&itar,path)){ gboolean is_active; gtk_tree_model_get(GTK_TREE_MODEL(window->list),&itar,0,&is_active,-1); gtk_list_store_set(window->list,&itar,0,!is_active,-1); } } int once_active=0; int valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(window->list),&iter); for (;valid;valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(window->list),&iter)){ int is_active; gtk_tree_model_get(GTK_TREE_MODEL(window->list),&iter,0,&is_active,-1); if (is_active){ once_active=1; break; } } if (!once_active) gtk_widget_set_sensitive(window->SaveButton,0); else gtk_widget_set_sensitive(window->SaveButton,1); } template_saving_window *yon_saving_window_new(){ GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path_saving); template_saving_window *window = malloc(sizeof(template_saving_window)); window->Window = yon_gtk_builder_get_widget(builder,"Window"); window->HeaderImage = yon_gtk_builder_get_widget(builder,"HeaderImage"); window->HeaderTopic = yon_gtk_builder_get_widget(builder,"HeaderTopic"); window->StatusBox = yon_gtk_builder_get_widget(builder,"StatusBox"); window->ParametersTree = yon_gtk_builder_get_widget(builder,"ParametersTree"); window->SaveButton = yon_gtk_builder_get_widget(builder,"SaveButton"); window->CancelButton = yon_gtk_builder_get_widget(builder,"CancelButton"); window->ToggleCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"ToggleCell")); window->list = GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore1")); window->OldValueColumn = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder,"OldValueColumn")); window->OldValueCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"OldValueCell")); window->NewValueColumn = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder,"NewValueColumn")); window->NewValueCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"NewValueCell")); window->filteredModel = GTK_TREE_MODEL(gtk_builder_get_object(builder,"listfilter1")); yon_window_config_custom_window_setup(GTK_WINDOW(window->Window),"SaveWindow"); char *icon_name = yon_char_append("com.ublinux.",template_app_information.app_tech_name); gtk_window_set_icon_name(GTK_WINDOW(window->Window),icon_name); gtk_window_set_title(GTK_WINDOW(window->Window),template_app_information.app_title); gtk_label_set_text(GTK_LABEL(window->HeaderTopic),template_app_information.app_title); gtk_image_set_from_pixbuf(GTK_IMAGE(window->HeaderImage),gtk_icon_theme_load_icon_for_scale(gtk_icon_theme_get_default(),yon_char_append("com.ublinux.",template_app_information.app_tech_name),32,1,GTK_ICON_LOOKUP_FORCE_SIZE,NULL)); g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_subwindow_close),NULL); g_signal_connect(G_OBJECT(window->SaveButton),"clicked", G_CALLBACK(on_save_parameters),window); g_signal_connect(G_OBJECT(window->ToggleCell),"toggled", G_CALLBACK(on_save_window_parameter_switched),window); return window; } /* ====================== config getting section ====================== */ char *yon_get_compare_config_command(va_list args,char *path,YON_CONFIG_TYPE type){ char *cur_command; char *compare_command=""; while ((cur_command=va_arg(args,char*))){ char *temp=cur_command; cur_command = yon_config_parameter_prepare_command(cur_command,type!=YON_CONFIG_CUSTOM?yon_config_get_type_path(type):path,NULL,NULL); char *temp_command = yon_char_unite(compare_command,!yon_char_is_empty(compare_command)?";":"",cur_command,NULL); if (!yon_char_is_empty(compare_command)) free(compare_command); compare_command = temp_command; } return yon_char_is_empty(compare_command)?NULL:compare_command; } void yon_save_window_loaded_config_init(template_saving_window *window, struct loaded_config *current_loaded, struct loaded_config *config_compare){ if (current_loaded){ struct loaded_config *current = NULL; for_dictionaries(current,current_loaded){ if (!yon_config_check_ignore(current->key)){ dictionary *dict = NULL; if (!yon_config_compare_ignore_get(current->key)){ dict = yon_dictionary_get((dictionary**)&config_compare,current->key); // get old parameter value } gboolean status=0; status = yon_config_get_status(current->key); if (dict&&!yon_char_is_empty((char*)dict->data)&&status!=-2){ if (strcmp((char*)dict->data,(char*)current->data)){ GtkTreeIter iter; if (status==0||status==-2) status = 0; else status=1; char *old_val = yon_char_new(current->data); char *new_val = yon_char_new(dict->data); if (strstr(old_val,"&")) {old_val = yon_char_replace(old_val,"&","\003");old_val = yon_char_replace(old_val,"\003","&");} if (strstr(old_val,">")) old_val = yon_char_replace(old_val,">",">"); if (strstr(old_val,"<")) old_val = yon_char_replace(old_val,"<","<"); if (strstr(new_val,"&")) {int sz = 0; config_str new_val_parsed = yon_char_parse(new_val,&sz,"&");new_val = yon_char_parsed_to_string(new_val_parsed,sz,"&"); yon_char_parsed_free(new_val_parsed,sz);} if (strstr(new_val,">")) new_val = yon_char_replace(new_val,">",">"); if (strstr(new_val,"<")) new_val = yon_char_replace(new_val,"<","<"); char *compare_string = yon_char_unite("",(char*)new_val,"\n",(char*)old_val,NULL); gtk_list_store_append(window->list,&iter); gtk_list_store_set(window->list,&iter,0,status,1,current->key,2,(char*)dict->data,3,(char*)current->data,4,compare_string,6,1,7,yon_config_get_section_for_key(current->key),-1); free(compare_string); } } else if ((strcmp((char*)current->data,""))&&status!=-2){ GtkTreeIter iter; if (status==0||status==-2) status = 0; else status=1; char *old_val = yon_char_new(current->data); if (strstr(old_val,"&")) {int sz = 0; config_str old_val_parsed = yon_char_parse(old_val,&sz,"&");old_val = yon_char_parsed_to_string(old_val_parsed,sz,"&"); yon_char_parsed_free(old_val_parsed,sz);} if (strstr(old_val,">")) old_val = yon_char_replace(old_val,">","<"); if (strstr(old_val,"<")) old_val = yon_char_replace(old_val,"<",">"); char *compare_string = yon_char_unite("\n",(char*)old_val,NULL); gtk_list_store_append(window->list,&iter); gtk_list_store_set(window->list,&iter,0,status,1,current->key,3,(char*)current->data,4,compare_string,6,1,7,yon_config_get_section_for_key(current->key),-1); free(compare_string); } } } } } void yon_save_window_compared_config_init_unfound(template_saving_window *window, struct loaded_config *current_loaded, struct loaded_config *config_compare){ if (config_compare){ struct loaded_config *current = NULL; for_dictionaries(current,config_compare){ if (!yon_config_check_ignore(current->key)){ GtkTreeIter iter; dictionary *dict = yon_dictionary_get((dictionary**)¤t_loaded,current->key); if (!dict){ GdkRGBA rgba; rgba.alpha=0.8; rgba.red=1; rgba.blue=0.3; rgba.green=0.65; char *rgba_string = gdk_rgba_to_string(&rgba); int status=0; char *compare_string = yon_char_unite((char*)current->data,"\n",NULL); gtk_list_store_append(window->list,&iter); gtk_list_store_set(window->list,&iter,0,0,1,current->key,2,(char*)current->data,4,compare_string,5,rgba_string,6,1,7,current->section,-1); free(compare_string); } } } } } int yon_config_parameter_prepare_elements(config_str target, int *size){ int success = 0; for (int i=0;i<(*size);i++){ char *start_bracket_replaced_string = yon_char_replace(target[i],"[","[\""); char *end_bracket_replaced_string = yon_char_replace(start_bracket_replaced_string,"]","\"]"); target[i] = end_bracket_replaced_string; } return success; } struct loaded_config *yon_config_convert_parameter(config_str parsed, int size){ struct loaded_config *loaded=NULL; for (int i=0;ikey=key; loaded->first=loaded; loaded->next=NULL; loaded->prev=NULL; loaded->section=NULL; loaded->data=value; } else { loaded->next = (struct loaded_config*)malloc(sizeof(struct loaded_config)); struct loaded_config *next=loaded->next; next->first=loaded->first; next->prev=loaded; next->key=key; next->first=loaded->first; next->next=NULL; next->section=NULL; next->data=value; loaded=next; } } return loaded; } char *yon_command_get_section(char *command){ int size=0; config_str parsed = yon_char_parse(command,&size," "); int get_pos = yon_char_parsed_check_exist(parsed,size,"get"); if (get_pos==-1) return NULL; char *final = yon_char_new(parsed[get_pos+1]); yon_char_parsed_free(parsed,size); return final; } config_str yon_command_get_parameters(char *command,int *parameters_size){ int size=0; config_str parameters = NULL; config_str parsed = yon_char_parse(command,&size," "); int get_pos = yon_char_parsed_check_exist(parsed,size,"get"); if (get_pos==-1) return NULL; for (int i=get_pos+2;idata)[i+1]!=NULL;i++){ if (strstr(((config_str)dict->data)[i],"[*]")){ char *search = yon_char_new(((config_str)dict->data)[i]); char *tmp = yon_char_divide_search(search,"[",-1); free(search); search = tmp; if (strstr(current->key,search)){ current->section = dict->key; } } else { if (!strcmp(((config_str)dict->data)[i],current->key)){ current->section = dict->key; } } } } } } struct loaded_config *yon_config_get_compared(char *command){ if (command){ int size; config_str config = yon_config_load(command,&size); config_str temporary = NULL; int temp_size=0; if (config&&size>0){ for (int i=0;iChooseFolderCheck); yon_gtk_window_setup(GTK_WINDOW(dialog->Window),NULL,template_app_information.app_title,yon_char_unite("com.ublinux.",template_app_information.app_tech_name,NULL),"ConfigFilechooserWindow"); gtk_label_set_text(GTK_LABEL(dialog->HeaderTopic),template_app_information.app_title); GtkFileFilter *filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter,"*.ini"); gtk_file_filter_set_name(filter, "*.ini"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog->MainFileChooser),filter); if (type==GTK_FILE_CHOOSER_ACTION_SAVE){ // yon_file_chooser_set_button_label(yon_char_get_localised_from_lib(LOAD_CONFIG_LABEL)); } if (yon_file_chooser_start(dialog)!=GTK_RESPONSE_CANCEL){ char *file = dialog->last_success_selection; if (!yon_char_is_empty(file)){ if (!strstr(file,".ini")) file = yon_char_append(file,".ini"); if (access(file,0)!=F_OK){ char *command_creation = ubconfig_file_create(file); int a = system(command_creation); free(command_creation); if (access(file,0)!=F_OK){ yon_ubl_status_box_render(CUSTOM_CONFIG_CREATION_ERROR_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); return NULL; } } } char *path = yon_char_unite("'",file,"'",NULL); free(file); gtk_widget_destroy(dialog->Window); return path; } return NULL; } /* ============ init section ============ */ void on_save_parameters(GtkWidget *self, template_saving_window *window){ yon_ubl_status_box_render(yon_char_get_localised_from_lib(SAVE_PROCESS_LABEL),BACKGROUND_IMAGE_INFO_TYPE); int saved_size; struct loaded_config *saved_parameters = yon_save_window_get_saved_parameters(window); int size=0; config_str commands = yon_loaded_config_convert_to_save_command(saved_parameters,&size,window->type!=YON_CONFIG_CUSTOM? yon_config_get_type_path(window->type):window->custom_save_path); yon_config_parameter_prepare_elements(commands,&size); char *final_command = yon_char_parsed_to_string(commands,size,";"); pthread_t thread_id; pthread_create(&thread_id, NULL, (void *)_yon_saving_threaded,final_command); yon_window_config_custom_window_set(GTK_WINDOW(window->Window),"SaveWindow"); on_subwindow_close(self); } template_debug_window *template_debugger_window_new(){ template_debug_window *window = malloc(sizeof(template_debug_window)); GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path_debug); window->Window=yon_gtk_builder_get_widget(builder,"Window"); window->HeaderTopic=yon_gtk_builder_get_widget(builder,"HeaderTopic"); window->HeaderImage=yon_gtk_builder_get_widget(builder,"HeaderImage"); window->StatusBox=yon_gtk_builder_get_widget(builder,"StatusBox"); window->Vte=yon_gtk_builder_get_widget(builder,"DebuggerTerminal"); gtk_window_set_title(GTK_WINDOW(window->Window),template_app_information.app_title); gtk_label_set_text(GTK_LABEL(window->HeaderTopic),template_app_information.app_title); gtk_window_set_icon_name(GTK_WINDOW(window->Window),yon_char_append("com.ublinux.",template_app_information.app_tech_name)); gtk_image_set_from_pixbuf(GTK_IMAGE(window->HeaderImage),gtk_icon_theme_load_icon_for_scale(gtk_icon_theme_get_default(),yon_char_append("com.ublinux.",template_app_information.app_tech_name),32,1,GTK_ICON_LOOKUP_FORCE_SIZE,NULL)); yon_window_config_custom_window_setup(GTK_WINDOW(window->Window),"DebugWindow"); return window; } template_saving_window *yon_save_proceed(char *path,YON_CONFIG_TYPE type, ...){ template_app_information = yon_ubl_get_app_info(); char *config_to_save = NULL; config_to_save = yon_config_get_type_path(type); if (!path&&type == YON_CONFIG_CUSTOM){ path = yon_custom_config_init(GTK_FILE_CHOOSER_ACTION_SAVE); if (!path) return NULL; } va_list args; struct loaded_config *config_compare=NULL; va_start(args,type); char *compare_command = yon_get_compare_config_command(args,path,type); config_compare = yon_config_get_compared(compare_command); // get compare config template_saving_window *window = yon_saving_window_new(); yon_save_window_set_status(window,path,type); int current_size=0; config_str current_config = yon_config_get_all(¤t_size); // get INTERNAL config struct loaded_config *current_loaded = yon_config_convert_parameter(current_config,current_size); // convert INTERNAL config into struct yon_save_window_loaded_config_init(window,current_loaded,config_compare); yon_save_window_compared_config_init_unfound(window,current_loaded,config_compare); if (!yon_save_window_destroy_if_empty(window)) return NULL; gtk_tree_view_set_model(GTK_TREE_VIEW(window->ParametersTree),GTK_TREE_MODEL(window->list)); gtk_widget_show(window->Window); on_save_window_parameter_switched(NULL,NULL,window); return window; }