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 @@
+
+
+
+
+
+
+
+
diff --git a/libublsettingsui-gtk3.pot b/libublsettingsui-gtk3.pot
index 3526d15..f87abcf 100644
--- a/libublsettingsui-gtk3.pot
+++ b/libublsettingsui-gtk3.pot
@@ -144,7 +144,7 @@ msgid "Cancel"
msgstr ""
#: source/libublsettingsui-gtk3.h:418
-msgid "Accept"
+msgid "Ok"
msgstr ""
#: source/libublsettingsui-gtk3.h:419
@@ -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 3254a6e..d84a9a9 100644
--- a/libublsettingsui-gtk3_ru.po
+++ b/libublsettingsui-gtk3_ru.po
@@ -146,7 +146,7 @@ msgid "Cancel"
msgstr "Отмена"
#: source/libublsettingsui-gtk3.h:418
-msgid "Accept"
+msgid "Ok"
msgstr "Принять"
#: source/libublsettingsui-gtk3.h:419
@@ -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-save.c b/source/libublsettingsui-gtk3-save.c
index 22e5f37..f6e56d6 100644
--- a/source/libublsettingsui-gtk3-save.c
+++ b/source/libublsettingsui-gtk3-save.c
@@ -508,23 +508,11 @@ struct loaded_config *yon_config_get_compared(char *command){
}
char *yon_custom_config_init(GtkFileChooserAction type){
- filechooser_window *dialog = yon_file_chooser_window_new(type);
+ filechooser_window *dialog = yon_config_file_chooser_window_new(type);
gtk_widget_hide(dialog->ChooseFolderCheck);
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),filter);
- GtkFileFilter *filter_json = gtk_file_filter_new();
- gtk_file_filter_add_pattern(filter_json,"*.json");
- gtk_file_filter_set_name(filter_json, "*.json");
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter_json);
- GtkFileFilter *filter_yaml = gtk_file_filter_new();
- gtk_file_filter_add_pattern(filter_yaml,"*.yaml");
- gtk_file_filter_set_name(filter_yaml, "*.yaml");
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter_yaml);
if (type==GTK_FILE_CHOOSER_ACTION_SAVE){
// yon_file_chooser_set_button_label(yon_char_get_localised_from_lib(LOAD_CONFIG_LABEL));
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 b74e640..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;
@@ -614,7 +623,7 @@ yon_window *yon_window_new();
#define LOAD_CONFIG_LABEL _("Load file")
#define CANCEL_LABEL _("Cancel")
- #define ACCEPT_LABEL _("Accept")
+ #define ACCEPT_LABEL yon_char_get_localised_from_lib("Ok")
#define OPEN_LABEL _("Open")
#define CREATE_FOLDER_LABEL _("Create directory")
#define SELECT_FOLDER_LABEL _("Select directory")