From 24d7c72a124df20339a50bb61e66385352e68a1b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 14 Jul 2009 11:54:46 +0000
Subject: Loaded the last project at startup.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@92 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog           |  20 ++++++++++
 src/configuration.c |  94 +++++++++++++++++++++++++++++++++++++++-----
 src/configuration.h |  21 ++++++++++
 src/editor.c        |  25 ++++++------
 src/main.c          |  17 ++++++++
 src/params.h        |  17 ++++----
 src/project.c       | 109 +++++++++++++++++++++++++++++++---------------------
 src/project.h       |   8 +++-
 8 files changed, 238 insertions(+), 73 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 701095d..efce196 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+09-07-14  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/configuration.c:
+	* src/configuration.h:
+	Load configuration files using the XDG directory. Define and provide the
+	value of string parameters.
+
+	* src/editor.c:
+	Clean the code and update calls.
+
+	* src/main.c:
+	Load the last project at startup.
+
+	* src/params.h:
+	Update the definition of the main parameters.
+
+	* src/project.c:
+	* src/project.h:
+	Clean the code. Manage the recent projects list.
+
 09-07-12  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/binary.c:
diff --git a/src/configuration.c b/src/configuration.c
index f7cdfbe..de4f2f1 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -29,12 +29,12 @@
 #include <string.h>
 
 
+#include "xdg.h"
 #include "xml.h"
 #include "common/extstr.h"
 
 
 
-
 /* Paramètres de configuration */
 struct _configuration
 {
@@ -50,8 +50,6 @@ struct _configuration
 
 
 
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : name   = désignation de la configuration.                    *
@@ -69,22 +67,41 @@ struct _configuration
 configuration *load_configuration(const char *name, config_param *params, unsigned int count)
 {
     configuration *result;                  /* Structure à retourner       */
-    char *home;                             /* Répertoire de l'utilisateur */
+    char *suffix;                           /* Fin du nom de fichier       */
+    unsigned int i;                         /* Boucle de parcours          */
+    char *strval;                           /* Valeur en chaîne de carac.  */
 
     result = (configuration *)calloc(1, sizeof(configuration));
 
     result->params = params;
     result->count = count;
 
-    /* FIXME : créer le répertoire, et en XDG */
-    home = strdup(getenv("HOME") != NULL ? getenv("HOME") : "");
-    result->filename = stradd(home, "/.openida/");
-    result->filename = stradd(result->filename, name);
-    result->filename = stradd(result->filename, ".xml");
+    suffix = strdup("openida/");
+    suffix = stradd(suffix, name);
+    suffix = stradd(suffix, ".xml");
+
+    result->filename = get_xdg_config_dir(suffix);
+
+    free(suffix);
 
     if (!open_xml_file(result->filename, &result->xdoc, &result->context))
         create_new_xml_file(&result->xdoc, &result->context);
 
+    else
+        for (i = 0; i < count; i++)
+            switch (params[i].type)
+            {
+                case CVT_STRING:
+                    strval = get_node_text_value(result->context, params[i].path);
+                    set_string_config_value(result, i, strval);
+                    if (strval != NULL) free(strval);
+                    break;
+
+                default:
+                    break;
+
+            }
+
     return result;
 
 }
@@ -123,3 +140,62 @@ void unload_configuration(configuration *config)
     free(config);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : config = configuration à venir consulter.                    *
+*                index  = indice de l'élément à traiter.                      *
+*                value  = valeur à considérer comme valeur courante.          *
+*                                                                             *
+*  Description : Définit une chaîne de caractères dans la configuration.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool set_string_config_value(configuration *config, unsigned int index, const char *value)
+{
+    if (index >= config->count) return false;
+    if (config->params[index].type != CVT_STRING) return false;
+
+    config->params[index].defined = true;
+
+    if (config->params[index].cur.string != NULL)
+        free(config->params[index].cur.string);
+
+    config->params[index].cur.string = (value != NULL ? strdup(value) : NULL);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : config = configuration à venir consulter.                    *
+*                index  = indice de l'élément à traiter.                      *
+*                                                                             *
+*  Description : Fournit une chaîne de caractères issue de la configuration.  *
+*                                                                             *
+*  Retour      : Valeur courante ou par défaut de la configuration.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *get_string_config_value(configuration *config, unsigned int index)
+{
+    const char *result;                     /* Valeur à retourner          */
+
+    if (index >= config->count) return NULL;
+    if (config->params[index].type != CVT_STRING) return NULL;
+
+    if (config->params[index].defined) result = config->params[index].cur.string;
+    else result = config->params[index].def.string;
+
+    return result;
+
+}
diff --git a/src/configuration.h b/src/configuration.h
index c86e1e1..645b17e 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -25,6 +25,17 @@
 #define _CONFIGURATION_H
 
 
+#include <stdbool.h>
+
+
+/* Tyoes de valeur pour élement de configuration */
+typedef enum _ConfigValueType
+{
+    CVT_STRING,                             /* Chaîne de caractère         */
+
+    CVT_COUNT
+
+} ConfigValueType;
 
 /* Valeurs supportées par les configurations */
 typedef union _config_value
@@ -38,6 +49,10 @@ typedef struct _config_param
 {
     const char *path;                       /* Chemin d'accès XML          */
 
+    ConfigValueType type;                   /* Type de valeur              */
+
+    bool defined;                           /* Présence de valeur courante */
+
     config_value def;                       /* Valeur par défaut           */
     config_value cur;                       /* Valeur courante             */
 
@@ -54,6 +69,12 @@ configuration *load_configuration(const char *, config_param *, unsigned int);
 /* Décharge la configuration principale. */
 void unload_configuration(configuration *);
 
+/* Définit une chaîne de caractères dans la configuration. */
+bool set_string_config_value(configuration *, unsigned int, const char *);
+
+/* Fournit une chaîne de caractères issue de la configuration. */
+const char *get_string_config_value(configuration *, unsigned int);
+
 
 
 #endif  /* _CONFIGURATION_H */
diff --git a/src/editor.c b/src/editor.c
index 2738621..eed74fb 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -184,7 +184,6 @@ GtkWidget *create_editor(void)
   GtkWidget *panel;
 
 
-  openida_project *project;
 
 
 
@@ -357,14 +356,6 @@ GtkWidget *create_editor(void)
 
 
 
-    load_recent_openida_projects_list(G_OBJECT(result), G_CALLBACK(mcb_open_recent_project));
-
-
-    project = create_empty_openida_project();
-    set_current_openida_project(project);
-
-    reload_menu_project(G_OBJECT(result));
-
 
 
   vpaned1 = gtk_vpaned_new ();
@@ -522,6 +513,11 @@ GtkWidget *create_editor(void)
 
 
 
+    load_recent_openida_projects_list(G_OBJECT(result), G_CALLBACK(mcb_open_recent_project));
+
+
+    reload_menu_project(G_OBJECT(result));
+
 
 
     return result;
@@ -620,7 +616,10 @@ void mcb_file_save_project(GtkMenuItem *menuitem, gpointer data)
     project = get_current_openida_project();
 
     if (has_storing_filename(project))
-        g_openida_project_save(project, NULL);
+    {
+        if (g_openida_project_save(project, NULL))
+            push_openida_project_into_recent_list(project);
+    }
 
     else
         mcb_file_save_project_as(menuitem, data);
@@ -644,6 +643,7 @@ void mcb_file_save_project(GtkMenuItem *menuitem, gpointer data)
 void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data)
 {
     GtkWidget *dialog;                      /* Boîte à afficher            */
+    openida_project *project;               /* Projet courant              */
     gchar *filename;                        /* Nom du fichier à intégrer   */
 
     dialog = gtk_file_chooser_dialog_new (_("Save the project as..."), GTK_WINDOW(data),
@@ -654,9 +654,12 @@ void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data)
 
     if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
     {
+        project = get_current_openida_project();
+
         filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
-        g_openida_project_save(get_current_openida_project(), filename);
+        if (g_openida_project_save(project, filename))
+            push_openida_project_into_recent_list(project);
 
         g_free(filename);
 
diff --git a/src/main.c b/src/main.c
index 0d51fa9..cc78897 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,6 +30,7 @@
 
 #include "editor.h"
 #include "params.h"
+#include "project.h"
 #include "arch/processor.h"
 #include "format/exe_format.h"
 #include "format/mangling/demangler.h"
@@ -55,8 +56,11 @@ int main(int argc, char **argv)
 {
     configuration *config;                  /* Configuration principale    */
     GtkWidget *editor;                      /* Fenêtre graphique           */
+    const char *filename;                   /* Chemin du dernier projet    */
+    openida_project *project;               /* Nouveau projet courant      */
 
     config = load_configuration("main", main_params, MPT_COUNT);
+    set_main_configuration(config);
 
     setlocale(LC_ALL, "");
     /*
@@ -93,6 +97,19 @@ int main(int argc, char **argv)
 
     init_all_plugins(G_OBJECT(editor));
 
+    /* Charge le dernier projet */
+
+    filename = get_string_config_value(config, MPT_RECENT_PROJECT_1);
+
+    if (filename == NULL) project = create_empty_openida_project();
+    else project = g_openida_project_new_from_xml(filename);
+
+    set_current_openida_project(project);
+
+    display_openida_project(project, G_OBJECT(editor));
+
+    /* Exécution du programme */
+
     gdk_threads_enter();
     gtk_main();
     gdk_threads_leave();
diff --git a/src/params.h b/src/params.h
index 25e2dcf..c37ef9f 100644
--- a/src/params.h
+++ b/src/params.h
@@ -52,18 +52,19 @@ typedef enum _MainParamType
 
 static config_param main_params[MPT_COUNT] = {
 
-    [MPT_RECENT_PROJECT_1] = { "/OpenIDA/Recents/Project1", NULL, NULL },
-    [MPT_RECENT_PROJECT_2] = { "/OpenIDA/Recents/Project2", NULL, NULL },
-    [MPT_RECENT_PROJECT_3] = { "/OpenIDA/Recents/Project3", NULL, NULL },
-    [MPT_RECENT_PROJECT_4] = { "/OpenIDA/Recents/Project4", NULL, NULL },
-    [MPT_RECENT_PROJECT_5] = { "/OpenIDA/Recents/Project5", NULL, NULL },
-    [MPT_RECENT_PROJECT_6] = { "/OpenIDA/Recents/Project6", NULL, NULL },
-    [MPT_RECENT_PROJECT_7] = { "/OpenIDA/Recents/Project7", NULL, NULL },
+    [MPT_RECENT_PROJECT_1] = { "/OpenIDA/Recents/Project1", CVT_STRING, false, NULL, NULL },
+    [MPT_RECENT_PROJECT_2] = { "/OpenIDA/Recents/Project2", CVT_STRING, false, NULL, NULL },
+    [MPT_RECENT_PROJECT_3] = { "/OpenIDA/Recents/Project3", CVT_STRING, false, NULL, NULL },
+    [MPT_RECENT_PROJECT_4] = { "/OpenIDA/Recents/Project4", CVT_STRING, false, NULL, NULL },
+    [MPT_RECENT_PROJECT_5] = { "/OpenIDA/Recents/Project5", CVT_STRING, false, NULL, NULL },
+    [MPT_RECENT_PROJECT_6] = { "/OpenIDA/Recents/Project6", CVT_STRING, false, NULL, NULL },
+    [MPT_RECENT_PROJECT_7] = { "/OpenIDA/Recents/Project7", CVT_STRING, false, NULL, NULL },
 
 };
 
 
-#define get_main_configuration() get_main_configuration(NULL)
+#define set_main_configuration(cfg) _get_main_configuration(cfg)
+#define get_main_configuration() _get_main_configuration(NULL)
 
 
 /* Fournit un lien vers la configuration principale. */
diff --git a/src/project.c b/src/project.c
index 9273b94..21a3380 100644
--- a/src/project.c
+++ b/src/project.c
@@ -24,14 +24,11 @@
 #include "project.h"
 
 
-#include <dirent.h>
 #include <malloc.h>
-#include <stdio.h>
 #include <string.h>
-#include <unistd.h>
 
 
-#include "xdg.h"
+#include "params.h"
 #include "xml.h"
 #include "gtkext/easygtk.h"
 #include "gtkext/gtkblockview.h"
@@ -504,6 +501,60 @@ const openida_binary **get_openida_project_binaries(const openida_project *proje
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : project = projet à traiter.                                  *
+*                                                                             *
+*  Description : Place un projet au sommet de la pile des projets récents.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void push_openida_project_into_recent_list(const openida_project *project)
+{
+    configuration *config;                  /* Configuration principale    */
+    unsigned int i;                         /* Boucle de parcours          */
+    const char *filename;                   /* Chemin d'un projet donné    */
+
+    pop_openida_project_from_recent_list(project);
+
+    config = get_main_configuration();
+
+    for (i = MPT_RECENT_PROJECT_7; i > MPT_RECENT_PROJECT_1; i--)
+    {
+        filename = get_string_config_value(config, i - 1);
+        set_string_config_value(config, i, filename);
+    }
+
+    set_string_config_value(config, MPT_RECENT_PROJECT_1, project->filename);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : project = projet à traiter.                                  *
+*                                                                             *
+*  Description : Retire un projet de la pile des projets récents.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void pop_openida_project_from_recent_list(const openida_project *project)
+{
+
+
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : ref  = espace global de référencement.                       *
 *                func = fonction à appeler lors d'un clic sur les menus.      *
 *                                                                             *
@@ -515,17 +566,14 @@ const openida_binary **get_openida_project_binaries(const openida_project *proje
 *                                                                             *
 ******************************************************************************/
 
-void load_recent_openida_projects_list(GObject *ref, GCallback *func)
+void load_recent_openida_projects_list(GObject *ref, GCallback func)
 {
     gboolean one_entry;                     /* Au moins en entrée chargée  */
     GtkWidget *menuitem;                    /* Menu principal à compléter  */
     GtkWidget *menubar;                     /* Support pour éléments       */
-    char *directory;                        /* Répertoire prévu pour proj. */
-    DIR *dir;                               /* Répertoire avec contenu ?   */
-    struct dirent *entry;                   /* Elément de répertoire       */
-    char *filename;                         /* Nom de fichier à ouvrir     */
-    char realfile[PATH_MAX];                /* Nom du fichier pointé       */
-    ssize_t ret;                            /* Bilan de la lecture         */
+    configuration *config;                  /* Configuration principale    */
+    unsigned int i;                         /* Boucle de parcours          */
+    const char *filename;                   /* Nom de fichier à ouvrir     */
     GtkWidget *submenuitem;                 /* Sous-menu à ajouter         */
 
     one_entry = false;
@@ -533,50 +581,23 @@ void load_recent_openida_projects_list(GObject *ref, GCallback *func)
     menuitem = GTK_WIDGET(g_object_get_data(ref, "menu_recent_prjs"));
     menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem));
 
-    directory = get_xdg_config_dir("openida/recents");
-
-    dir = opendir(directory);
-    /* TODO :: check */
+    config = get_main_configuration();
 
-    if (dir != NULL)
+    for (i = MPT_RECENT_PROJECT_1; i <= MPT_RECENT_PROJECT_7; i++)
     {
-        for (entry = readdir(dir); entry != NULL; entry = readdir(dir))
-        {
-            if (strcmp(entry->d_name, ".") == 0) continue;
-            if (strcmp(entry->d_name, "..") == 0) continue;
-
-            if (strlen(entry->d_name) <= 4) continue;
-            if (strcmp(&entry->d_name[strlen(entry->d_name) - 4], ".xml") != 0) continue;
-
-            filename = (char *)calloc(strlen(directory) + 2 + strlen(entry->d_name) + 1, sizeof(char));
-            strcpy(filename, directory);
-            strcat(filename, "/");
-            strcat(filename, entry->d_name);
-
-            ret = readlink(filename, realfile, PATH_MAX);
-            /* TODO :: check */
-
-            if (ret == -1) goto process_next_recent;
+        filename = get_string_config_value(config, i);
 
-            submenuitem = qck_create_menu_item(NULL, NULL, realfile, func, ref);
+        if (filename != NULL)
+        {
+            submenuitem = qck_create_menu_item(NULL, NULL, filename, func, ref);
             gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
             one_entry = true;
 
-        process_next_recent:
-
-            free(filename);
-
         }
 
-        closedir(dir);
-
     }
 
-    free(directory);
-
- recent_list_end:
-
     gtk_widget_set_sensitive(menuitem, one_entry);
 
 }
diff --git a/src/project.h b/src/project.h
index 80b9507..9142ecb 100644
--- a/src/project.h
+++ b/src/project.h
@@ -94,8 +94,14 @@ const openida_binary **get_openida_project_binaries(const openida_project *, siz
 /* ---------------------- PARTIE GRAPHIQUE DES [DE]CHARGEMENTS ---------------------- */
 
 
+/* Place un projet au sommet de la pile des projets récents. */
+void push_openida_project_into_recent_list(const openida_project *);
+
+/* Retire un projet de la pile des projets récents. */
+void pop_openida_project_from_recent_list(const openida_project *);
+
 /* Met en place les menus rechargeant les projets récents. */
-void load_recent_openida_projects_list(GObject *, GCallback *);
+void load_recent_openida_projects_list(GObject *, GCallback);
 
 /* Met en place un projet à l'écran. */
 void display_openida_project(const openida_project *, GObject *);
-- 
cgit v0.11.2-87-g4458