/* oupis-window.c
*
* Copyright 2026 Thomas Arnoux
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "oupis-window.h"
struct _OupisWindow
{
AdwApplicationWindow parent_instance;
/* Template widgets */
GtkSearchEntry *searchentry;
GtkScrolledWindow *scrolledwindow;
GtkListView *listview;
GtkSingleSelection *singleselection;
GListStore *liststore;
};
G_DEFINE_FINAL_TYPE (OupisWindow, oupis_window, ADW_TYPE_APPLICATION_WINDOW)
static gchar*
str_to_lc_ascii (const gchar* string)
{
gchar* str_lc_ascii;
str_lc_ascii = g_utf8_strdown (string, -1);
return g_str_to_ascii (str_lc_ascii, NULL);
}
static void
chercher_una (GMatchInfo *match_info,
OupisWindow *window)
{
const gchar* procdir = "/home/vetetix/Code/Gendarmerie/Oupis/procedures";
//gchar proctype[][6];
GDateTime *now;
gint year;
int unite;
int numero;
int annee;
// Il vaudrait mieux utiliser la fonction g_ascii_strtoll puis transformer le
// gint64 en int (https://stackoverflow.com/questions/3298612/uint64-t-to-int)
// mais atoi devrait être suffisamment sûr puisque les variables ont été
// validées par la regex.
unite = atoi (g_match_info_fetch_named (match_info, "unite"));
numero = atoi (g_match_info_fetch_named (match_info, "numero"));
annee = atoi (g_match_info_fetch_named (match_info, "annee"));
g_print ("unite: %.5i\n", unite);
g_print ("numero: %.5i\n", numero);
g_print ("annee: %.4i\n", annee);
g_autoptr(GStrvBuilder) builder = g_strv_builder_new ();
g_strv_builder_add_many (builder,
"Administratif",
"Judiciaire",
"Courriers",
"MainCourante",
"Militaire",
NULL);
g_auto(GStrv) proctype = g_strv_builder_end (builder);
g_autoptr (GFile) category_dir;
g_autoptr (GFileEnumerator) direnum;
g_autoptr (GFileInfo) info;
g_autoptr (GFile) file;
GError *error = NULL;
gchar* infoname;
gchar* infoname_lc_ascii;
int i=0;
for (i=0; i < g_strv_length (proctype); i++ ) {
category_dir = g_file_new_build_filename (procdir,
proctype[i],
NULL);
g_print ("%s\n", g_file_get_path (category_dir));
//TODO rendre async et gérer les erreurs
direnum = g_file_enumerate_children (category_dir,
"standard::name,standard::display-name,standard::type",
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
if (error) {
g_print("%s\n", error->message);
error = NULL;
return;
}
while (TRUE)
{
if (!g_file_enumerator_iterate (direnum, &info, &file, NULL, &error))
goto out;
if (!info)
break;
g_print ("%s\n", g_file_get_path (file));
infoname = g_file_info_get_name (info);
/*infoname_lc_ascii = str_to_lc_ascii (infoname);
if (g_strrstr (infoname_lc_ascii, request_lc_ascii)) {
g_print ("%s\n", infoname);
g_list_store_insert (window->liststore, 0, file);
}*/
}
out:
if (error) {
g_print("%s\n", error->message);
error = NULL;
return;
}
//g_object_unref (direnum); // Note: frees the last @info
}
g_error_free (error);
now = g_date_time_new_now_local ();
year = g_date_time_get_year (now);
g_print ("%i\n",year);
}
static void
oupis_window__search_request (GtkSearchEntry *self,
OupisWindow *window)
{
const char* request;
char* request_lc_ascii;
GFile *directory;
GFileEnumerator *direnum;
GError *error = NULL;
GFileInfo *info;
GFile *file;
const gchar * infoname;
gchar * infoname_lc_ascii;
g_list_store_remove_all (window->liststore);
request = gtk_editable_get_text (GTK_EDITABLE (self));
g_print ("Request: %s\n", request);
request_lc_ascii = str_to_lc_ascii (request);
g_print (" R_l_a: %s\n", request_lc_ascii);
// On détermine le type de requête :
// - commande (/commande arguments)
// - una (UUUUU/NNNNN/AAAA)
// - texte (tout le reste)
// Gestion des commandes
if (g_pattern_match_simple ("/*", request_lc_ascii))
{
g_print ("C'est une commande\n");
return;
}
// Gestion des recherches d'UNA
const char *regex_pattern = "^(?:(?P[0-9]{0,5})(?=/[0-9]{1,5}/[0-9]{1,4})/)?(?P[0-9]{1,5})(?:/(?P[0-9]{1,4}))?$";
g_autoptr(GMatchInfo) match_info = NULL;
g_autoptr(GRegex) regex = NULL;
regex = g_regex_new (regex_pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
g_assert (regex != NULL);
if (g_regex_match (regex, request_lc_ascii, G_REGEX_MATCH_DEFAULT, &match_info))
{
int start_pos, end_pos;
g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos);
g_print ("Match successful! Overall pattern matches bytes %d to %d\n", start_pos, end_pos);
g_print ("Count: %i\n", g_match_info_get_match_count(match_info));
g_print ("0. %s\n", g_match_info_fetch (match_info, 0));
g_print ("1.U%s\n", g_match_info_fetch (match_info, 1));
g_print ("2.N%s\n", g_match_info_fetch (match_info, 2));
g_print ("3.A%s\n", g_match_info_fetch (match_info, 3));
g_print ("4. %s\n", g_match_info_fetch (match_info, 4));
g_print ("5. %s\n", g_match_info_fetch (match_info, 5));
g_print ("6. %s\n", g_match_info_fetch (match_info, 6));
g_print ("7. %s\n", g_match_info_fetch (match_info, 7));
chercher_una (match_info, window);
return;
}
else
{
g_print ("No match!\n");
}
directory = g_file_new_for_path (".");
direnum = g_file_enumerate_children (directory,
"standard::name,standard::display-name",
G_FILE_QUERY_INFO_NONE,
NULL,
NULL);
g_object_unref (directory);
while (TRUE)
{
if (!g_file_enumerator_iterate (direnum, &info, &file, NULL, &error))
goto out;
if (!info)
break;
infoname = g_file_info_get_name (info);
infoname_lc_ascii = str_to_lc_ascii (infoname);
if (g_strrstr (infoname_lc_ascii, request_lc_ascii)) {
g_print ("%s\n", infoname);
g_list_store_insert (window->liststore, 0, file);
}
}
out:
if (error) {
g_print("%s\n", error->message);
g_error_free (error);
}
g_object_unref (direnum); // Note: frees the last @info
g_free (request_lc_ascii);
g_free (infoname_lc_ascii);
}
static void
listview_activate (GtkListView *listview, int position, OupisWindow *window) {
GError *error = NULL;
GFile *file = G_FILE (g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (listview)), position));;
//GFileInfo *info = G_FILE_INFO (g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (listview)), position));
g_print ("%s\n", g_file_get_basename (file));
//file = G_FILE (g_file_info_get_attribute_object (info, "standard::file"));
//TODO rendre cet appel async et gérer les éventuelles erreurs
g_app_info_launch_default_for_uri (g_file_get_uri (file), NULL, &error);
if (error){
g_print ("%s\n", error->message);
}
g_object_unref (file);
}
static GIcon *
get_icon (GtkListItem *item, GFileInfo *info) {
GIcon *icon;
/* g_file_info_get_icon can return NULL */
//TODO corriger ou supprimer
icon = G_IS_FILE_INFO (info) ? g_file_info_get_icon (info) : NULL;
return icon ? g_object_ref (icon) : NULL;
}
static char *
get_file_name (GtkListItem *item, GFile *file) {
return G_IS_FILE (file) ? g_strdup (g_file_get_basename (file)) : NULL;
}
static void
oupis_window_class_init (OupisWindowClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template_from_resource (widget_class, "/lu/arnoux/Oupis/oupis-window.ui");
gtk_widget_class_bind_template_child (widget_class, OupisWindow, searchentry);
gtk_widget_class_bind_template_child (widget_class, OupisWindow, scrolledwindow);
gtk_widget_class_bind_template_child (widget_class, OupisWindow, listview);
gtk_widget_class_bind_template_child (widget_class, OupisWindow, singleselection);
gtk_widget_class_bind_template_child (widget_class, OupisWindow, liststore);
gtk_widget_class_bind_template_callback (widget_class, oupis_window__search_request);
gtk_widget_class_bind_template_callback (widget_class, listview_activate);
gtk_widget_class_bind_template_callback (widget_class, get_icon);
gtk_widget_class_bind_template_callback (widget_class, get_file_name);
}
static void
oupis_window_init (OupisWindow *self)
{
GFile *file;
gtk_widget_init_template (GTK_WIDGET (self) );
gtk_widget_grab_focus (GTK_WIDGET (self->searchentry));
file = g_file_new_for_path (".");
//gtk_directory_list_set_file (GTK_DIRECTORY_LIST (self->directorylist), file);
g_object_unref (file);
}