From 09c67288a09c1225b5ead49cce5ae2bb9bbd01a2 Mon Sep 17 00:00:00 2001 From: Ivan Dmitrievich Yartsev Date: Tue, 30 Dec 2025 13:39:45 +0000 Subject: [PATCH] Added user selection window --- gresource.xml | 1 + libublsettingsui-gtk3-users-window.glade | 170 ++++++++++++++++++++ libublsettingsui-gtk3.pot | 3 + libublsettingsui-gtk3_ru.po | 5 +- source/CMakeLists.txt | 2 + source/libublsettingsui-gtk3-users-window.c | 132 +++++++++++++++ source/libublsettingsui-gtk3.h | 11 +- 7 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 libublsettingsui-gtk3-users-window.glade create mode 100644 source/libublsettingsui-gtk3-users-window.c diff --git a/gresource.xml b/gresource.xml index db00251..5aab596 100644 --- a/gresource.xml +++ b/gresource.xml @@ -12,6 +12,7 @@ libublsettingsui-gtk3-service-control.glade libublsettingsui-gtk3-app-chooser.glade libublsettingsui-gtk3-password.glade + libublsettingsui-gtk3-users-window.glade libublsettingsui-gtk3.css diff --git a/libublsettingsui-gtk3-users-window.glade b/libublsettingsui-gtk3-users-window.glade new file mode 100644 index 0000000..8698736 --- /dev/null +++ b/libublsettingsui-gtk3-users-window.glade @@ -0,0 +1,170 @@ + + + + + + True + False + com.ublinux.libublsettingsui-gtk3.cancel-symbolic + + + True + False + com.ublinux.libublsettingsui-gtk3.accept-symbolic + + + 250 + 385 + False + True + com.ublinux.ubl-settings-usergroups + + + True + False + vertical + + + True + False + + + + + + False + True + 0 + + + + + True + False + 5 + 5 + 5 + 5 + 5 + 5 + vertical + 5 + + + True + True + in + + + True + True + 2 + vertical + + + + + + Chosen + + + True + + + 0 + + + + + + + ID + True + 2 + + + + 2 + + + + + + + Group + descending + 1 + + + + 1 + + + + + + + + + True + True + 1 + + + + + True + True + 1 + + + + + + + True + False + + + True + False + Choose groups + + + + + + + + Cancel + True + True + True + image5 + + + + + + Ok + True + True + True + image6 + + + + end + 1 + + + + + + diff --git a/libublsettingsui-gtk3.pot b/libublsettingsui-gtk3.pot index c507f7f..f87abcf 100644 --- a/libublsettingsui-gtk3.pot +++ b/libublsettingsui-gtk3.pot @@ -391,4 +391,7 @@ msgstr "" #: source/libublsettingsui-gtk3.h:493 msgid "The configuration file contains incorrect parameters." +msgstr "" + +msgid "Empty important field!" msgstr "" \ No newline at end of file diff --git a/libublsettingsui-gtk3_ru.po b/libublsettingsui-gtk3_ru.po index d56a7a5..d84a9a9 100644 --- a/libublsettingsui-gtk3_ru.po +++ b/libublsettingsui-gtk3_ru.po @@ -397,4 +397,7 @@ msgid "Access to file denied" msgstr "Отказано в доступе к файлу" msgid "The configuration file contains incorrect parameters." -msgstr "Файл конфигурации содержит некорректные параметры" \ No newline at end of file +msgstr "Файл конфигурации содержит некорректные параметры" + +msgid "Empty important field!" +msgstr "Пустое важное поле!" \ No newline at end of file diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 190acd1..92729b9 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -48,6 +48,7 @@ set(DEPENDFILES ../libublsettingsui-gtk3-service-control.glade ../libublsettingsui-gtk3-app-chooser.glade ../libublsettingsui-gtk3-password.glade + ../libublsettingsui-gtk3-users-window.glade ../gresource.xml ../libublsettingsui-gtk3-banner.png ../libublsettingsui-gtk3.css @@ -89,6 +90,7 @@ add_library(${PROJECT_NAME} SHARED libublsettingsui-gtk3-app-chooser.c libublsettingsui-gtk3-standard-callbacks.c libublsettingsui-gtk3-password.c + libublsettingsui-gtk3-users-window.c libublsettingsui-gtk3.h ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}) diff --git a/source/libublsettingsui-gtk3-users-window.c b/source/libublsettingsui-gtk3-users-window.c new file mode 100644 index 0000000..134537c --- /dev/null +++ b/source/libublsettingsui-gtk3-users-window.c @@ -0,0 +1,132 @@ +#include "libublsettingsui-gtk3.h" + +typedef struct { + GtkWidget *Window; + GtkWidget *StatusBox; + GtkWidget *UsersTree; + GtkListStore *list; + GtkWidget *CancelButton; + GtkWidget *AcceptButton; + GtkCellRenderer *StatusCell; + GtkTreeViewColumn *GroupColumn; + unsigned int selection_size; + config_str selection; +} yon_user_window; + +gboolean on_user_window_closed(GtkWidget *, yon_user_window *){ + gtk_main_quit(); + return 0; +} + +void on_group_clicked(GtkCellRenderer *, char *path, yon_user_window *window){ + GtkTreeIter iter; + gboolean status; + gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(window->list),&iter,path); + gtk_tree_model_get(GTK_TREE_MODEL(window->list),&iter,0,&status,-1); + gtk_list_store_set(window->list,&iter,0,!status,-1); + if (gtk_cell_renderer_toggle_get_radio(GTK_CELL_RENDERER_TOGGLE(window->StatusCell))){ + GtkTreeIter *prev = gtk_tree_iter_copy(&iter); + for (int valid = gtk_tree_model_iter_previous(GTK_TREE_MODEL(window->list),prev); valid; valid = gtk_tree_model_iter_previous(GTK_TREE_MODEL(window->list),prev)){ + gtk_list_store_set(window->list,prev,0,0,-1); + } + gtk_tree_iter_free(prev); + + GtkTreeIter *next = gtk_tree_iter_copy(&iter); + for (int valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(window->list),next); valid; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(window->list),next)){ + gtk_list_store_set(window->list,next,0,0,-1); + } + gtk_tree_iter_free(next); + } +} + +void on_users_window_accept(GtkWidget *, yon_user_window *window){ + GtkTreeModel *model; + GList *list = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(window->UsersTree)),&model); + GList *liter; + for (liter=list;liter;liter=liter->next){ + GtkTreeIter iter; + gtk_tree_model_get_iter(model,&iter,(GtkTreePath*)liter->data); + int selected; + char *target; + int id; + gtk_tree_model_get(model,&iter,0,&selected,1,&target,2,&id,-1); + if (selected){ + char *id_string = yon_char_from_int(id); + yon_char_parsed_add_or_create_if_exists(window->selection,&window->selection_size,target); //FIXME: IMPLEMENT USER AND GROUP SYSTEM AND SWITCH TARGET TO UID/GID + free(id_string); + } + } + on_subwindow_close(window->Window); +} + +yon_user_window *yon_user_window_new(enum YON_USER_WINDOW_MODE_TYPE mode){ + yon_user_window *window = malloc(sizeof(yon_user_window)); + memset(window,0,sizeof(yon_user_window)); + GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path_userwindow); + window->Window=yon_gtk_builder_get_widget(builder,"Window"); + window->StatusBox=yon_gtk_builder_get_widget(builder,"StatusBox"); + window->UsersTree=yon_gtk_builder_get_widget(builder,"UsersTree"); + window->StatusCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"StatusCell")); + window->GroupColumn = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder,"GroupColumn")); + window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton"); + window->AcceptButton=yon_gtk_builder_get_widget(builder,"AcceptButton"); + window->list = gtk_list_store_new(3,G_TYPE_BOOLEAN,G_TYPE_STRING,G_TYPE_INT); + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(window->list),2,GTK_SORT_ASCENDING); + + yon_gtk_window_setup(GTK_WINDOW(window->Window),NULL,NULL,NULL,"GroupWindow"); + + g_signal_connect(G_OBJECT(window->Window),"destroy",G_CALLBACK(on_user_window_closed),window); + g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_subwindow_close),NULL); + g_signal_connect(G_OBJECT(window->AcceptButton),"clicked",G_CALLBACK(on_users_window_accept),window); + g_signal_connect(G_OBJECT(window->StatusCell),"toggled",G_CALLBACK(on_group_clicked),window); + GtkTreeIter iter; + switch (mode){ + case YON_USER_WINDOW_USERS_MULTIPLE: + gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(window->StatusCell),0); + [[fallthrough]]; + case YON_USER_WINDOW_USERS:{ + int size; + config_str system_param = yon_file_open("/etc/passwd",&size); + for (int i=0;i2&&!yon_char_is_empty(parsed[2])){ + gtk_list_store_append(window->list,&iter); + gtk_list_store_set(window->list,&iter,0,0,1,parsed[0],2,atoi(parsed[2]),-1); + } + } + } break; + + case YON_USER_WINDOW_GROUPS_MULTIPLE: + gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(window->StatusCell),0); + [[fallthrough]]; + case YON_USER_WINDOW_GROUPS:{ + int size; + config_str system_param = yon_file_open("/etc/group",&size); + for (int i=0;i2&&!yon_char_is_empty(parsed[2])){ + gtk_list_store_append(window->list,&iter); + gtk_list_store_set(window->list,&iter,0,0,1,parsed[0],2,atoi(parsed[2]),-1); + } + } + } break; + } + gtk_tree_view_set_model(GTK_TREE_VIEW(window->UsersTree),GTK_TREE_MODEL(window->list)); + + + g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_subwindow_close),NULL); +return window; +} + +config_str yon_users_window_select(enum YON_USER_WINDOW_MODE_TYPE mode, unsigned int *size){ + (*size) = 0; + yon_user_window *window = yon_user_window_new(mode); + gtk_widget_show(window->Window); + gtk_main(); + (*size) = window->selection_size; + config_str ret = window->selection; + free(window); + return ret; +} diff --git a/source/libublsettingsui-gtk3.h b/source/libublsettingsui-gtk3.h index 8e3b3d0..c40ebec 100644 --- a/source/libublsettingsui-gtk3.h +++ b/source/libublsettingsui-gtk3.h @@ -26,7 +26,7 @@ #define ui_glade_path_window "/com/ublinux/ui/libublsettingsui-gtk3-window.glade" - +#define ui_glade_path_userwindow "/com/ublinux/ui/libublsettingsui-gtk3-users-window.glade" /**Путь до файла подтверждения открытия документации утилит ubl-settings-**/ #define ui_glade_path_documentation "/com/ublinux/ui/libublsettingsui-gtk3-documentation.glade" @@ -365,6 +365,15 @@ void yon_window_remove_exit_config_check(template_main_window *widgets); void yon_window_set_exit_config_check(template_main_window *widgets, GCallback data_callback_function); +enum YON_USER_WINDOW_MODE_TYPE { + YON_USER_WINDOW_USERS, + YON_USER_WINDOW_USERS_MULTIPLE, + YON_USER_WINDOW_GROUPS, + YON_USER_WINDOW_GROUPS_MULTIPLE +}; + +config_str yon_users_window_select(enum YON_USER_WINDOW_MODE_TYPE mode, unsigned int *size); + typedef struct { GtkWidget *Window; GtkWidget *HeaderTopic;