From e85aa7545ac75843a9469337a205b100f6d7ceab Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Sat, 2 Sep 2023 14:31:40 +0600 Subject: [PATCH] Added file chooser and application chooser --- gresource.xml | 1 + source/CMakeLists.txt | 1 + source/ubl-strings.h | 14 +++- source/ubl-utils.c | 87 ++++++++++++++++++----- source/ubl-utils.h | 12 +++- source/ublexec.c | 74 +++++++++++++------- source/ublexec.h | 38 ++++++---- ublexec-application.glade | 142 ++++++++++---------------------------- ublexec.glade | 7 ++ 9 files changed, 210 insertions(+), 166 deletions(-) diff --git a/gresource.xml b/gresource.xml index 67946e6..a2846f6 100644 --- a/gresource.xml +++ b/gresource.xml @@ -2,6 +2,7 @@ ublexec.glade + ublexec-application.glade ublexec.css diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index bb6b66b..7091ce7 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -36,6 +36,7 @@ add_custom_target(GLADE ublexec.glade) set(DEPENDFILES ../ublexec.glade + ../ublexec-application.glade ../gresource.xml ../ublexec-banner.png ../ublexec.css diff --git a/source/ubl-strings.h b/source/ubl-strings.h index e169970..78c45b0 100644 --- a/source/ubl-strings.h +++ b/source/ubl-strings.h @@ -10,9 +10,21 @@ #define DOCUMENTATION_LABEL _("Documentation") #define CANCEL_LABEL _("Cancel") +#define OPEN_LABEL _("Open") #define HELP_TITLE_LABEL _("Would you like to read documentation in the Web?") #define HELP_INFO_LABEL _("You will be redirected to documentation website where documentation is\ntranslated and supported by community.") #define HELP_ALWAYS_OPEN_LABEL _("Always redirect to online documentation") #define OPEN_HELP_LABEL _("Open documentation") -#define PROJECT_HOME_LABEL _("Project homepage") \ No newline at end of file +#define PROJECT_HOME_LABEL _("Project homepage") + +#define GRAPHICS_LABEL _("Graphics") +#define TOOLS_LABEL _("Tools") +#define INTERNET_LABEL _("Internet") +#define MULTIMEDIA_LABEL _("Multimedia") +#define SETTINGS_LABEL _("Settings") +#define EDUCATION_LABEL _("Education") +#define OFFICE_LABEL _("Office") +#define OTHER_LABEL _("Other") +#define DEVELOPMENT_LABEL _("Development") +#define SYSTEM_LABEL _("System") \ No newline at end of file diff --git a/source/ubl-utils.c b/source/ubl-utils.c index 28ce67d..b4b1d6d 100644 --- a/source/ubl-utils.c +++ b/source/ubl-utils.c @@ -932,6 +932,7 @@ apps *yon_apps_scan_and_parse_desktops(int *sizef) if (size == 0) { applist = (apps *)malloc(size + 1 * sizeof(apps)); + applist[0].filename = yon_char_new(path); applist[0].Name = yon_char_new(tempapp.Name); applist[0].Categories = yon_char_new(tempapp.Categories); applist[0].Exec = yon_char_new(tempapp.Exec); @@ -944,6 +945,7 @@ apps *yon_apps_scan_and_parse_desktops(int *sizef) else { applist = (apps *)realloc(applist, (size + 1) * sizeof(apps)); + applist[size].filename = yon_char_new(path); applist[size].Name = yon_char_new(tempapp.Name); applist[size].Categories = yon_char_new(tempapp.Categories); applist[size].Exec = yon_char_new(tempapp.Exec); @@ -992,27 +994,72 @@ apps *yon_apps_get_by_name(apps *applist, char *name, int size) return NULL; }; -char *yon_app_chooser_open_with_sections(char *section_name,...){ - GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL,5); - GtkWidget *main_tree = gtk_tree_view_new(); - GtkTreeStore *store = gtk_tree_store_new(1,G_TYPE_STRING,-1); - gtk_tree_view_set_model(GTK_TREE_VIEW(main_tree),GTK_TREE_MODEL(store)); - GtkWidget *cancel_button = gtk_button_new(); - GtkWidget *accept_button = gtk_button_new(); - GtkWidget *button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5); - gtk_container_add(GTK_CONTAINER(window),box); - gtk_box_pack_start(GTK_BOX(box),main_tree,1,1,5); - gtk_box_pack_end(GTK_BOX(box),button_box,0,0,5); - gtk_box_pack_end(GTK_BOX(button_box),accept_button,0,0,5); - gtk_box_pack_end(GTK_BOX(button_box),cancel_button,0,0,5); +/**yon_app_chooser_open_with_sections(char *section_name, char *section_filter, char *section_icon, ...) + * [EN] + * + * [RU] + * Вызывает диалоговое окно выбора приложений с разделом [section_name], разделом [section_filter] и иконкой, полученной по названию [section_icon]. + * после них можно вводить любое количество пар названий раздела и названий иконок для получения дополнительных разделов, + * оканчивающиеся NULL. +*/ +char *yon_app_chooser_open_with_sections(char *section_name, char *section_filter, char *section_icon, ...){ + GtkBuilder *builder = gtk_builder_new_from_resource("/com/ublinux/ui/ublexec-application.glade"); + GtkWidget *dialog = gtk_dialog_new(); + gtk_widget_set_size_request(dialog,500,600); + gtk_window_set_icon_name(GTK_WINDOW(dialog),"com.ublinux.ublexec"); + gtk_window_set_title(GTK_WINDOW(dialog),_("Applications")); + gtk_dialog_add_buttons(GTK_DIALOG(dialog),_("Cancel"),0,_("Accept"),1,NULL); + GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder,"ApplicationsWindow")); + GtkWidget *box = GTK_WIDGET(gtk_builder_get_object(builder,"box")); + g_object_ref(box); + gtk_container_remove(GTK_CONTAINER(window),box); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),box,1,1,5); + GtkWidget *main_tree = GTK_WIDGET(gtk_builder_get_object(builder,"MainTree")); + GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(builder,"treestore1")); va_list args; - va_start(args,section_name); - GtkWidget *widget = va_arg(args,GtkWidget*); - while (widget){ - + GtkTreeIter iter, childiter; + gtk_tree_store_append(GTK_TREE_STORE(store),&iter,NULL); + gtk_tree_store_set(GTK_TREE_STORE(store),&iter,0,section_icon,1,section_name,2,section_filter,-1); + va_start(args,section_icon); + char *section; + while ((section = va_arg(args,char*))){ + char *filter = va_arg(args,char*); + char *icon = va_arg(args,char*); + if (icon&&filter){ + gtk_tree_store_append(GTK_TREE_STORE(store),&iter,NULL); + gtk_tree_store_set(GTK_TREE_STORE(store),&iter,0,icon,1,section,2,filter,-1); + } } va_end(args); + int size; + apps *app_list = yon_apps_scan_and_parse_desktops(&size); + int valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store),&iter); + for (; valid; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store),&iter)){ + char *cur_categories; + gtk_tree_model_get(GTK_TREE_MODEL(store),&iter,2,&cur_categories,-1); + for (int i=0; i #include #include +#include #include #include #include @@ -20,7 +21,10 @@ #include "ubl-cmake.h" #ifdef WEBKIT_FOUND #include -#endif +#endif + +#define _(String) gettext(String) + #define DesktopPath "/usr/share/applications/" #define try bool __HadError=false; #define catch(x) ExitJmp:if(__HadError) @@ -61,6 +65,7 @@ typedef struct dictionary typedef struct apps { + char *filename; char *Name; int Type; char *Categories; @@ -189,6 +194,8 @@ void yon_apps_sort(apps *applist, int size); apps *yon_apps_get_by_name(apps *applist, char *name, int size); +char *yon_app_chooser_open_with_sections(char *section_name, char *section_filter, char *section_icon, ...); + config_str yon_config_load(char *command, int *str_len); int yon_config_save_registered(char *path, char *section); @@ -281,6 +288,9 @@ void yon_gtk_column_minimal_fixed_size_set(GtkTreeViewColumn *column); int yon_gtk_icon_view_hide_empty(dictionary *icon_view_segment); +void yon_subwindow_close(GtkWidget *self); + + int yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); int yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); diff --git a/source/ublexec.c b/source/ublexec.c index 1c539d9..b152f54 100644 --- a/source/ublexec.c +++ b/source/ublexec.c @@ -102,12 +102,34 @@ void on_about(){ //functions -void yon_load_proceed(char *command){ - if (yon_config_load_register(command)) - yon_ubl_status_box_render(LOCAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE); - else - yon_ubl_status_box_render(LOAD_FAILED_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); - +void on_file_chooser_open(GtkWidget *self, main_window *widgets){ + GtkWidget *dialog = gtk_file_chooser_dialog_new(TITLE_LABEL,NULL,GTK_FILE_CHOOSER_ACTION_OPEN,CANCEL_LABEL,GTK_RESPONSE_CANCEL,OPEN_LABEL,GTK_RESPONSE_ACCEPT,NULL); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),"/usr/bin/"); + gtk_window_set_icon_name(GTK_WINDOW(dialog),icon_path); + + int res = gtk_dialog_run(GTK_DIALOG(dialog)); + if (res==GTK_RESPONSE_ACCEPT){ + char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + gtk_entry_set_text(GTK_ENTRY(widgets->TargetNameEntry),filename); + } + on_close_subwindow(dialog); + +} + +void on_application_chooser_open(GtkWidget *self, main_window *widgets){ + char *app = yon_app_chooser_open_with_sections(GRAPHICS_LABEL,"Graphics","", + TOOLS_LABEL,"Graphics","", + INTERNET_LABEL,"Network","", + MULTIMEDIA_LABEL,"AudioVideo","", + SETTINGS_LABEL,"Settings","", + EDUCATION_LABEL,"Education","", + OFFICE_LABEL,"Office","", + OTHER_LABEL,"Utility","", + DEVELOPMENT_LABEL,"Development","", + SYSTEM_LABEL,"System","",NULL); + if (app){ + gtk_entry_set_text(GTK_ENTRY(widgets->TargetNameEntry),app); + } } // standard functions @@ -157,6 +179,10 @@ main_window *setup_window(){ widgets->runButton = yon_gtk_builder_get_widget(builder,"runButton"); + widgets->HeadOverlay = yon_gtk_builder_get_widget(builder,"overHead"); + widgets->HeadImage = yon_gtk_builder_get_widget(builder,"imgHeadBackground"); + widgets->HeadBox = yon_gtk_builder_get_widget(builder,"boxColor"); + widgets->DocumentationMenuItem = yon_ubl_menu_item_documentation_new(DOCUMENTATION_LABEL); widgets->AboutMenuItem = yon_ubl_menu_item_about_new(ABOUT_LABEL); @@ -166,18 +192,6 @@ main_window *setup_window(){ gtk_menu_shell_append(GTK_MENU_SHELL(menu),widgets->DocumentationMenuItem); gtk_menu_shell_append(GTK_MENU_SHELL(menu),widgets->AboutMenuItem); - if (main_config.lock_load_global == 1){ - gtk_widget_set_sensitive(widgets->LoadGlobalMenuItem,0); - } - if (main_config.lock_save_global == 1){ - gtk_widget_set_sensitive(widgets->SaveGlobalMenuItem,0); - gtk_widget_set_sensitive(widgets->SaveMenuItem,0); - } - if (main_config.lock_save_local == 1){ - gtk_widget_set_sensitive(widgets->SaveLocalMenuItem,0); - gtk_widget_set_sensitive(widgets->SaveMenuItem,0); - } - /* Widget registration for config monitoring | Регистрация виджетов для мониторинга конфига */ // yon_window_config_add_custom_parameter(widgets->HeadInfoLabel,"head-text","label",YON_TYPE_STRING); @@ -185,7 +199,24 @@ main_window *setup_window(){ g_signal_connect(G_OBJECT(widgets->Window), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(widgets->DocumentationMenuItem),"activate",G_CALLBACK(on_open_documentation_confirmation),WIKI_LINK); g_signal_connect(G_OBJECT(widgets->AboutMenuItem),"activate",G_CALLBACK(on_about),NULL); + g_signal_connect(G_OBJECT(widgets->chooseFileButton),"clicked",G_CALLBACK(on_file_chooser_open),widgets); + g_signal_connect(G_OBJECT(widgets->chooseDesktopButton),"clicked",G_CALLBACK(on_application_chooser_open),widgets); + + g_signal_connect(G_OBJECT(widgets->priorityCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->priorityScale); + g_signal_connect(G_OBJECT(widgets->priorityCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->prioritySpin); + + g_signal_connect(G_OBJECT(widgets->runWithUserCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->runWithUserPkexecCheck); + g_signal_connect(G_OBJECT(widgets->runWithUserCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->runWithUserSuCheck); + g_signal_connect(G_OBJECT(widgets->runWithUserCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->runWithUserSudoCheck); + g_signal_connect(G_OBJECT(widgets->runWithUserCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->runWithUserCombo); + + g_signal_connect(G_OBJECT(widgets->runWithTerminalCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->runWithTerminalCombo); + + g_signal_connect(G_OBJECT(widgets->commandCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button),widgets->commandEntry); + + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->runWithUserCombo),); gtk_widget_show(widgets->Window); return widgets; @@ -270,13 +301,6 @@ int main(int argc, char *argv[]){ main_window *widgets = setup_window(); yon_ubl_header_setup_resource(widgets->HeadOverlay,widgets->HeadBox,widgets->HeadImage,banner_path); - - yon_ubl_status_box_setup(widgets->StatusIcon,widgets->StatusBox,widgets->StatusLabel); - if (getuid()!=0) - yon_ubl_status_box_render(ROOT_WARNING_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); - else - yon_ubl_status_box_render(TITLE_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE); - yon_ubl_setup_sockets(widgets->PlugBox,widgets->LeftBox,widgets->RightBox,main_config.socket_id,main_config.load_socket_id,main_config.save_socket_id); yon_window_config_setup(GTK_WINDOW(widgets->Window)); yon_window_config_load(config_path); GtkCssProvider *css=gtk_css_provider_new(); diff --git a/source/ublexec.h b/source/ublexec.h index 2bb0188..b07942c 100644 --- a/source/ublexec.h +++ b/source/ublexec.h @@ -7,7 +7,6 @@ #include #include #include -#include #include "../compile/ubl-cmake.h" #ifdef WEBKIT_FOUND #include @@ -21,6 +20,7 @@ #define glade_path "/com/ublinux/ui/ublexec.glade" #define banner_path "/com/ublinux/images/ublexec-banner.png" #define CssPath "/com/ublinux/css/ublexec.css" +#define icon_path "com.ublinux.ublexec" #define config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL) #define LocalePath "/usr/share/locale" @@ -59,23 +59,31 @@ typedef struct { GtkWidget *HeadTitleLabel; GtkWidget *HeadInfoLabel; - GtkWidget *StatusBox; - GtkWidget *StatusIcon; - GtkWidget *StatusLabel; + GtkWidget *TargetNameEntry; + GtkWidget *AboutMenuItem; + GtkWidget *DocumentationMenuItem; - GtkWidget *SaveLabel; - GtkWidget *SaveMenuItem; - GtkWidget *SaveGlobalMenuItem; - GtkWidget *SaveLocalMenuItem; - GtkWidget *RightBox; + GtkWidget *targetNameEntry; + GtkWidget *chooseFileButton; + GtkWidget *chooseDesktopButton; + GtkWidget *runWithTerminalCheck; + GtkWidget *runWithTerminalCombo; - GtkWidget *LoadLabel; - GtkWidget *LoadGlobalMenuItem; - GtkWidget *LoadLocalMenuItem; - GtkWidget *LeftBox; + GtkWidget *runWithUserCheck; + GtkWidget *runWithUserPkexecCheck; + GtkWidget *runWithUserSuCheck; + GtkWidget *runWithUserSudoCheck; - GtkWidget *DocumentationMenuItem; - GtkWidget *AboutMenuItem; + GtkWidget *runWithUserCombo; + GtkWidget *priorityCheck; + GtkWidget *priorityScale; + GtkWidget *prioritySpin; + GtkWidget *highestPriorityLabel; + + GtkWidget *commandCheck; + GtkWidget *commandEntry; + + GtkWidget *runButton; // Custom } main_window; diff --git a/ublexec-application.glade b/ublexec-application.glade index 363dafe..2a8d720 100644 --- a/ublexec-application.glade +++ b/ublexec-application.glade @@ -2,31 +2,23 @@ - - True - False - process-stop-symbolic - - - True - False - emblem-ok-symbolic - - + + + - + - - 800 + + 500 600 False com.ublinux.ublexec - + True False 5 @@ -36,27 +28,35 @@ vertical 5 - + True True - treestore1 - - - + in - - Name - - - - 0 - - + + True + True + treestore1 + False + treeviewcolumn1 - - - 1 - + + column + + + 4 + + + 0 + + + + + + 1 + + + @@ -67,60 +67,19 @@ 0 - - - True - False - 5 - - - Ok - True - True - True - image2 - - - False - True - end - 1 - - - - - Cancel - True - True - True - image1 - - - False - True - end - 2 - - - - - False - True - 1 - - - + True False + True - + True False center - Run as... + Applications @@ -134,35 +93,6 @@ com.ublinux.ublexec - - - True - False - - - True - True - False - True - True - menu1 - none - - - - - - False - True - 0 - - - - - end - 1 - - diff --git a/ublexec.glade b/ublexec.glade index 36e5a0e..40a6989 100644 --- a/ublexec.glade +++ b/ublexec.glade @@ -1370,6 +1370,7 @@ pkexec True + False True False 6 @@ -1386,6 +1387,7 @@ su True + False True False True @@ -1401,6 +1403,7 @@ sudo True + False True False True @@ -1551,9 +1554,11 @@ True + False True 15 adjustment1 + True 20 0 0 @@ -1567,8 +1572,10 @@ True + False True center + adjustment1 True