diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/editor.c | 4 | ||||
| -rw-r--r-- | src/gui/menus/file.c | 18 | ||||
| -rw-r--r-- | src/gui/panels/Makefile.am | 3 | ||||
| -rw-r--r-- | src/gui/panels/log.c | 6 | ||||
| -rw-r--r-- | src/gui/panels/log.h | 2 | ||||
| -rw-r--r-- | src/gui/panels/panel-int.h | 29 | ||||
| -rw-r--r-- | src/gui/panels/panel.c | 577 | ||||
| -rw-r--r-- | src/gui/panels/panel.h | 2 | ||||
| -rw-r--r-- | src/gui/panels/symbols.h | 2 | ||||
| -rw-r--r-- | src/gui/panels/welcome.c | 179 | ||||
| -rw-r--r-- | src/gui/panels/welcome.h | 65 | ||||
| -rw-r--r-- | src/main.c | 4 | ||||
| -rw-r--r-- | src/project.c | 13 | ||||
| -rw-r--r-- | src/project.h | 4 | 
14 files changed, 582 insertions, 326 deletions
| diff --git a/src/editor.c b/src/editor.c index 3c861d1..81feb14 100644 --- a/src/editor.c +++ b/src/editor.c @@ -286,7 +286,7 @@ GtkWidget *create_editor(void)      menuboard = gtk_menu_bar_new();      gtk_widget_show(menuboard); -    gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); +    //gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0);      /* Affichage */ @@ -397,7 +397,7 @@ GtkWidget *create_editor(void) -#if 1 +#if 0    vpaned1 = gtk_vpaned_new ();    gtk_widget_show (vpaned1);    //gtk_box_pack_start (GTK_BOX (vbox1), vpaned1, TRUE, TRUE, 0); diff --git a/src/gui/menus/file.c b/src/gui/menus/file.c index 8d218c1..3c204e0 100644 --- a/src/gui/menus/file.c +++ b/src/gui/menus/file.c @@ -34,10 +34,10 @@  /* Réagit au menu "Fichier -> Nouveau projet". */ -static void mcb_file_new_project(GtkMenuItem *, gpointer); +static void mcb_file_new_project(GtkMenuItem *, GObject *);  /* Réagit au menu "Fichier -> Ouvrir un projet". */ -static void mcb_file_open_project(GtkMenuItem *, gpointer); +static void mcb_file_open_project(GtkMenuItem *, GObject *);  /* Réagit au menu "Fichier -> Enregistrer le projet". */  static void mcb_file_save_project(GtkMenuItem *, gpointer); @@ -130,7 +130,7 @@ GtkWidget *build_menu_file(GObject *ref, GtkAccelGroup *accgroup)  /******************************************************************************  *                                                                             *  *  Paramètres  : menuitem = élément de menu sélectionné.                      * -*                data     = adresse de l'espace de référencement global.      * +*                ref      = adresse de l'espace de référencement global.      *  *                                                                             *  *  Description : Réagit au menu "Fichier -> Nouveau projet".                  *  *                                                                             * @@ -140,11 +140,11 @@ GtkWidget *build_menu_file(GObject *ref, GtkAccelGroup *accgroup)  *                                                                             *  ******************************************************************************/ -static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) +static void mcb_file_new_project(GtkMenuItem *menuitem, GObject *ref)  {      GStudyProject *project;                 /* Nouveau projet courant      */ -    project = g_study_project_new(); +    project = g_study_project_new(ref);      set_current_project(project); @@ -156,7 +156,7 @@ static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data)  /******************************************************************************  *                                                                             *  *  Paramètres  : menuitem = élément de menu sélectionné.                      * -*                data     = adresse de l'espace de référencement global.      * +*                ref      = adresse de l'espace de référencement global.      *  *                                                                             *  *  Description : Réagit au menu "Fichier -> Ouvrir un projet".                *  *                                                                             * @@ -166,13 +166,13 @@ static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data)  *                                                                             *  ******************************************************************************/ -static void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) +static void mcb_file_open_project(GtkMenuItem *menuitem, GObject *ref)  {      GtkWidget *dialog;                      /* Boîte à afficher            */      GStudyProject *project;                 /* Projet chargé               */      gchar *filename;                        /* Nom du fichier à intégrer   */ -    dialog = gtk_file_chooser_dialog_new(_("Open a project"), GTK_WINDOW(data), +    dialog = gtk_file_chooser_dialog_new(_("Open a project"), GTK_WINDOW(ref),                                           GTK_FILE_CHOOSER_ACTION_OPEN,                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,                                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, @@ -188,7 +188,7 @@ static void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data)      {          filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); -        project = g_study_project_open(filename); +        project = g_study_project_open(ref, filename);          if (project != NULL)          { diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am index 0d43844..2678d54 100644 --- a/src/gui/panels/Makefile.am +++ b/src/gui/panels/Makefile.am @@ -4,7 +4,8 @@ noinst_LTLIBRARIES  = libguipanels.la  libguipanels_la_SOURCES =				\  	log.h log.c							\  	panel.h panel.c						\ -	symbols.h symbols.c +	symbols.h symbols.c					\ +	welcome.h welcome.c  libguipanels_la_LDFLAGS =  diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index 6bda922..0baa3a4 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -50,7 +50,7 @@ static GtkWidget *build_log_panel(void);  /******************************************************************************  *                                                                             * -*  Paramètres  : -                                                            * +*  Paramètres  : ref = espace de référencement global.                        *  *                                                                             *  *  Description : Construit le panneau d'affichage des messages système.       *  *                                                                             * @@ -60,14 +60,14 @@ static GtkWidget *build_log_panel(void);  *                                                                             *  ******************************************************************************/ -GPanelItem *create_log_panel(void) +GPanelItem *create_log_panel(GObject *ref)  {      GEditorItem *result;                    /* Elément réactif à renvoyer  */      GtkWidget *panel;                       /* Composant GTK visuel        */      panel = build_log_panel(); -    result = g_panel_item_new(PANEL_LOG_ID, _("Misc information"), panel, "S"); +    result = g_panel_item_new(ref, PANEL_LOG_ID, _("Misc information"), panel, "S");      return G_PANEL_ITEM(result); diff --git a/src/gui/panels/log.h b/src/gui/panels/log.h index 264078c..4644d76 100644 --- a/src/gui/panels/log.h +++ b/src/gui/panels/log.h @@ -55,7 +55,7 @@ typedef enum _LogMessageType  /* Construit le panneau d'affichage des messages système. */ -GPanelItem *create_log_panel(void); +GPanelItem *create_log_panel(GObject *);  /* Affiche un message dans le journal des messages système. */  void log_simple_message(LogMessageType, const char *); diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h index 133f1a3..e1c8932 100644 --- a/src/gui/panels/panel-int.h +++ b/src/gui/panels/panel-int.h @@ -51,6 +51,35 @@ struct _GPanelItem  }; +/* Elément de la hiérarchie des panneaux */ +typedef struct _panel_node +{ +    struct _panel_node *parent;             /* Noeud parent                */ + +    char path;                              /* Chemin du nom courant       */ +    size_t depth;                           /* Profondeur utilisée         */ + +    bool simple;                            /* Noeud sans division         */ + +    union +    { +        GtkWidget *station;                 /* Station d'accueil simple    */ + +        struct +        { +            GtkWidget *paned;               /* Station d'accueil composée  */ +            struct _panel_node *first;      /* Premier sous élément        */ +            struct _panel_node *second;     /* Second sous élément         */ +        }; + +    }; + +} panel_node; + + +#define GET_PANEL_NODE_WIDGET(node) (node->simple ? node->station : node->paned) + +  /* Elément réactif pour panneaux de l'éditeur (classe) */  struct _GPanelItemClass  { diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index b13c074..f70a1ab 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -32,6 +32,7 @@  #include "log.h"  #include "panel-int.h"  #include "symbols.h" +#include "welcome.h"  #include "../../gtkext/easygtk.h"  #include "../../gtkext/gtkdockstation.h" @@ -39,6 +40,7 @@  /* Support de fond pour les composants. */  static GtkWidget *_support; +static panel_node *_nodes = NULL;  /* Procédure à appeler lors des changements de panneaux. */  static GCallback _handler; @@ -54,20 +56,28 @@ static void g_panel_item_class_init(GPanelItemClass *);  /* Initialise une instance d'élément réactif pour l'éditeur. */  static void g_panel_item_init(GPanelItem *); -/* Renvoie un élément du chemin d'insertion du panneau. */ -static char g_panel_item_get_path_at(GPanelItem *, size_t); -/* Détermine le support faisant office d'étendue donnée. */ -static GtkWidget *get_panel_given_part(GtkWidget *, size_t, char); -/* Fournit le premier morceau de chemin rencontré. */ -static char get_first_path_found(GtkWidget *, size_t); +/* ---------------------- MECANISMES DE PLACEMENT DES PANNEAUX ---------------------- */ -/* Introduit une nouvelle division sur le support indiqué. */ -static void create_panel_division(GtkWidget *, GtkWidget *, const char *, GtkWidget *, const char *, char); -/* Place un panneau dans l'ensemble affiché. */ -static void _g_panel_item_dock(GtkWidget *, GEditorItem *, const char *, size_t); +/* Crée un nouveau noeud pour un panneau particulier. */ +static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t); + +/* Prépare une nouvelle sous-division pour deux panneaux. */ +static void switch_panel_node_into_paned(panel_node *, bool, bool); + +/* Met en place un nouveau noeud dans une division. */ +static void attach_panel_node_to_paned(panel_node *, panel_node *, bool); + +/* Indique si un noeud correspond à la branche recherchée. */ +static bool is_panel_node_matching(const panel_node *, char); + +/* Place au bon endroit un panneau donné. */ +static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t); + +/* Met à jour l'affichage suite à un changement hiérarchique. */ +static void rebuild_panels_interface(const panel_node *); @@ -168,43 +178,19 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con  *                                                                             *  ******************************************************************************/ -GEditorItem *g_panel_item_new(const char *name, const char *lname, GtkWidget *widget, const char *path) +GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)  {      GPanelItem *result;                     /* Structure à retourner       */      result = g_object_new(G_TYPE_PANEL_ITEM, NULL); -    g_panel_item_init_ext(result, NULL/* FIXME */, name, lname, widget, path); +    g_panel_item_init_ext(result, ref, name, lname, widget, path);      return G_EDITOR_ITEM(result);  } - -/****************************************************************************** -*                                                                             * -*  Paramètres  : item = composant d'affichage à consulter.                    * -*                pos  = position de la tête de lecture dans le chemin.        * -*                                                                             * -*  Description : Renvoie un élément du chemin d'insertion du panneau.         * -*                                                                             * -*  Retour      : Lettre caractéristique ou '\0'.                              * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static char g_panel_item_get_path_at(GPanelItem *item, size_t pos) -{ -    if (pos >= strlen(item->path)) -        return '\0'; -    else -        return item->path[pos]; - -} - -  /******************************************************************************  *                                                                             *  *  Paramètres  : name = désignation courte servant de clef.                   * @@ -248,37 +234,13 @@ GPanelItem *g_panel_item_get(const char *name)  void g_panel_item_dock(GPanelItem *item)  { -    GPanelItemClass *class;                 /* Encadrement global          */ -    GtkWidget *station;                     /* Premier support concentré   */ -    GEditorItem *editem;                    /* Autre vision des choses     */ - -    class = G_PANEL_ITEM_GET_CLASS(item); -      /* Tout est à faire... */ -    if (class->first == NULL) +    if (_nodes == NULL)      { -        /** -         * Note : on crée ici un support qui ne sera jamais déplacé, -         * laissant ainsi la variable 'class->first' pour les départs -         * de parcours toujours valide sans effort. -         */ -        class->first = GTK_BIN(qck_create_padded_alignment(0, 0, 0, 0)); - -        gtk_widget_show(GTK_WIDGET(class->first)); -        gtk_container_add(GTK_CONTAINER(_support), GTK_WIDGET(class->first)); - -        station = gtk_dock_station_new(); -        g_signal_connect(station, "switch-widget", _handler, _data); - -        gtk_widget_show(station); -        gtk_container_add(GTK_CONTAINER(class->first), station); - -        editem = G_EDITOR_ITEM(item); -        gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), -                                  editem->widget, editem->name); - +        _nodes = create_simple_panel_node_for_item(item, item->path, 0); +        gtk_container_add(GTK_CONTAINER(_support), _nodes->station);      } -    else _g_panel_item_dock(gtk_bin_get_child(class->first), G_EDITOR_ITEM(item), item->path, 0); +    else insert_item_as_panel_node(item, _nodes, item->path, 0);  } @@ -307,93 +269,110 @@ void g_panel_item_undock(GPanelItem *item)  } + +/* ---------------------------------------------------------------------------------- */ +/*                         PLACEMENTS DES DIFFERENTS PANNEAUX                         */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : base   = support sujet à analyse.                            * -*                pos    = position de la tête de lecture dans le chemin.      * -*                target = indentifiant de positionnement recherché.           * +*  Paramètres  : handler = procédure à réveiller en cas de changements.       * +*                data    = donnée à faire suivre.                             *  *                                                                             * -*  Description : Détermine le support faisant office d'étendue donnée.        * +*  Description : Prépare le terrain pour l'affichage central.                 *  *                                                                             * -*  Retour      : Composant en place retrouvé ou NULL si aucune correspondance.* +*  Retour      : Composant de support sur lequel tout va se placer.           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static GtkWidget *get_panel_given_part(GtkWidget *base, size_t pos, char target) +GtkWidget *init_panels2(GCallback handler, gpointer data)  { -    GtkWidget *result;                      /* Trouvaille à retourner      */ -    GtkWidget *widget;                      /* Autre composant présent     */ -    GPanelItem *item;                       /* Autre version de l'instance */ -    char path;                              /* Partie de chemin en place   */ +    GtkWidget *result;                      /* Support à retourner         */ -    if (GTK_IS_DOCK_STATION(base)) -    { -        widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); -        item = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); +    result = qck_create_padded_alignment(0, 0, 0, 0); +    gtk_widget_show(result); -        path = g_panel_item_get_path_at(item, pos); +    _support = result; +    _handler = handler; +    _data = data; -        result = (path == target ? base : NULL); +    return result; -    } -    else -    { -        widget = gtk_paned_get_child1(GTK_PANED(base)); -        result = get_panel_given_part(widget, pos, target); +} -        if (result == NULL) -        { -            widget = gtk_paned_get_child2(GTK_PANED(base)); -            result = get_panel_given_part(widget, pos, target); -        } -    } +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencement global.                        * +*                                                                             * +*  Description : Charge les principaux panneaux de l'éditeur.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    return result; +void load_main_panels(GObject *ref) +{ +    GPanelItem *item;                       /* Panneau de base à charger   */ + +    item = create_welcome_panel(ref); +    g_panel_item_dock(item); + +    item = create_log_panel(ref); +    g_panel_item_dock(item); + +    item = create_symbols_panel(ref); +    g_panel_item_dock(item);  } +/* ---------------------------------------------------------------------------------- */ +/*                        MECANISMES DE PLACEMENT DES PANNEAUX                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : base = support sujet à analyse.                              * -*                pos  = position de la tête de lecture dans le chemin.        * +*  Paramètres  : item  = composant à présenter à l'affichage.                 * +*                path  = partie du chemin représentée ici.                    * +*                depth = profondeur du chemin utilisé.                        *  *                                                                             * -*  Description : Fournit le premier morceau de chemin rencontré.              * +*  Description : Crée un nouveau noeud pour un panneau particulier.           *  *                                                                             * -*  Retour      : Premier élément de chemin rencontré.                         * +*  Retour      : Structure d'accueil mise en place.                           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char get_first_path_found(GtkWidget *base, size_t pos) +static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path, size_t depth)  { -    char result;                            /* Trouvaille à retourner      */ -    GtkWidget *widget;                      /* Autre composant présent     */ -    GPanelItem *item;                       /* Autre version de l'instance */ +    panel_node *result;                     /* Structure à retourner       */ +    GtkWidget *station;                     /* Premier support concentré   */ +    GEditorItem *editem;                    /* Autre vision des choses     */ -    if (GTK_IS_DOCK_STATION(base)) -    { -        widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); -        item = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); +    result = (panel_node *)calloc(1, sizeof(panel_node)); -        result = g_panel_item_get_path_at(item, pos); +    result->path = path[depth]; +    result->depth = depth; -    } -    else -    { -        /** -         * A un certain niveau, si deux éléments sont groupés, -         * c'est qu'ils ont une base commune ! On ne parcourt donc -         * que le premier d'entre eux. -         */ -        widget = gtk_paned_get_child1(GTK_PANED(base)); -        result = get_first_path_found(widget, pos); +    result->simple = true; -    } +    station = gtk_dock_station_new(); +    g_signal_connect(station, "switch-widget", _handler, _data); +    gtk_widget_show(station); + +    result->station = station; + +    editem = G_EDITOR_ITEM(item); +    gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), +                              editem->widget, editem->name);      return result; @@ -402,14 +381,11 @@ static char get_first_path_found(GtkWidget *base, size_t pos)  /******************************************************************************  *                                                                             * -*  Paramètres  : parent      = support où placer la nouvelle division.        * -*                child1      = composant GTK à placer en position 1.          * -*                name1       = éventuelle désignation en cas d'isolement.     * -*                child2      = composant GTK à placer en position 2.          * -*                name2       = éventuelle désignation en cas d'isolement.     * -*                orientation = sens de la division.                           * +*  Paramètres  : item  = composant à présenter à l'affichage.                 * +*                horiz = indique le type d'orientation désiré.                * +*                first = indication sur l'emplacement à utiliser.             *  *                                                                             * -*  Description : Introduit une nouvelle division sur le support indiqué.      * +*  Description : Prépare une nouvelle sous-division pour deux panneaux.       *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -417,281 +393,282 @@ static char get_first_path_found(GtkWidget *base, size_t pos)  *                                                                             *  ******************************************************************************/ -static void create_panel_division(GtkWidget *parent, GtkWidget *child1, const char *name1, GtkWidget *child2, const char *name2, char orientation) +static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool first)  { -    unsigned int index;                     /* Indice de la réinsertion    */ -    bool resize;                            /* Redimensionnement à garder  */ -    GtkWidget *station;                     /* Nouvelle concentration      */ -    GtkWidget *paned;                       /* Nouveau support             */ +    panel_node *moved;                      /* Noeud descendu d'un étage   */ +    GtkWidget *widget;                      /* Composant à traiter         */ -    orientation = toupper(orientation); +    /* Descend l'élément actuel */ -    /* Détermination de la localisation d'origine */ +    moved = (panel_node *)calloc(1, sizeof(panel_node)); -    if (GTK_IS_PANED(parent)) -    { -        if (gtk_paned_get_child1(GTK_PANED(parent)) == child1 -            || gtk_paned_get_child1(GTK_PANED(parent)) == child2) -        { -            index = 1; -            resize = GTK_PANED(parent)->child1_resize; -        } -        else -        { -            index = 2; -            resize = GTK_PANED(parent)->child2_resize; -        } -    } +    memcpy(moved, current, sizeof(panel_node)); +    moved->parent = current; + +    widget = GET_PANEL_NODE_WIDGET(current); + +    g_object_ref(G_OBJECT(widget)); +    gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); + +    if (first) +        current->first = moved;      else -    { -        index = -1; -        resize = false; /* Pour gcc (Debian 4.4.5-8) 4.4.5 */ -    } +        current->second = moved; -    gtk_widget_ref(name1 == NULL ? child1 : child2); +    /* Achève la transformation */ -    gtk_container_remove(GTK_CONTAINER(parent), child2); +    current->path = '\0'; -    /* Enrobages éventuels */ +    current->simple = false; -    if (!GTK_IS_DOCK_STATION(child1)) -    { -        station = gtk_dock_station_new(); -        g_signal_connect(station, "switch-widget", _handler, _data); +    current->station = NULL; -        gtk_widget_show(station); -        gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), child1, name1); +    if (horiz) +        current->paned = gtk_hpaned_new(); +    else +        current->paned = gtk_vpaned_new(); -        child1 = station; +    gtk_widget_show(current->paned); -    } +    /* Replace le composant d'origine */ -    if (!GTK_IS_DOCK_STATION(child2)) -    { -        station = gtk_dock_station_new(); -        g_signal_connect(station, "switch-widget", _handler, _data); +    if (first) +        gtk_paned_add1(GTK_PANED(current->paned), widget); +    else +        gtk_paned_add2(GTK_PANED(current->paned), widget); -        gtk_widget_show(station); -        gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), child2, name2); +    g_object_unref(G_OBJECT(widget)); -        child2 = station; +} -    } -    /* Insertion complète */ +/****************************************************************************** +*                                                                             * +*  Paramètres  : parent = noeud d'accueil pour le nouveau noeud.              * +*                node   = nouveau noeud à intégrer dans l'ensemble.           * +*                first  = indication sur l'emplacement à utiliser.            * +*                                                                             * +*  Description : Met en place un nouveau noeud dans une division.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first) +{ +    GtkWidget *widget;                      /* Composant à traiter         */ + +    /* Raccordement hiérarchique */ -    if (orientation == 'N' || orientation == 'S') -        paned = gtk_vpaned_new(); +    if (first) +        parent->first = node;      else -        paned = gtk_hpaned_new(); +        parent->second = node; -    gtk_widget_show(paned); +    /* Raccordement graphique */ -    switch (index) -    { -        case 1: -            gtk_paned_pack1(GTK_PANED(parent), paned, resize, FALSE); -            break; -        case 2: -            gtk_paned_pack2(GTK_PANED(parent), paned, resize, FALSE); -            break; -        default: -            gtk_container_add(GTK_CONTAINER(parent), paned); -            break; -    } +    widget = GET_PANEL_NODE_WIDGET(node); -    switch (orientation) -    { -        case 'N': -            break; -        case 'E': -            gtk_paned_pack1(GTK_PANED(paned), child1, TRUE, FALSE); -            gtk_paned_pack2(GTK_PANED(paned), child2, FALSE, FALSE); -            gtk_paned_set_position(GTK_PANED(paned), 450); -            break; -        case 'S': -            gtk_paned_pack1(GTK_PANED(paned), child1, TRUE, FALSE); -            gtk_paned_pack2(GTK_PANED(paned), child2, FALSE, FALSE); -            gtk_paned_set_position(GTK_PANED(paned), 350); -            break; -        case 'W': -            break; -    } +    if (first) +        gtk_paned_add1(GTK_PANED(parent->paned), widget); +    else +        gtk_paned_add2(GTK_PANED(parent->paned), widget);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : base = départ courant de la déscente.                        * -*                item = composant à présenter à l'affichage.                  * -*                path = chemin à consulter pour le placement idéal.           * -*                pos  = position de la tête de lecture dans le chemin.        * +*  Paramètres  : node   = noeud d'où lancer les recherches.                   * +*                target = identifiant de la position visée.                   *  *                                                                             * -*  Description : Place un panneau dans l'ensemble affiché.                    * +*  Description : Indique si un noeud correspond à la branche recherchée.      *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Bilan de l'évaluation.                                       *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void _g_panel_item_dock(GtkWidget *base, GEditorItem *item, const char *path, size_t pos) +static bool is_panel_node_matching(const panel_node *node, char target)  { -    GtkWidget *part;                        /* Support principal détecté   */ -    GtkWidget *widget;                      /* Autre composant présent     */ -    GPanelItem *other;                      /* Autre version de l'instance */ -    char path_i;                            /* Partie de chemin à insérer  */ -    char path_o;                            /* Partie de chemin en place   */ -    GtkWidget *parent;                      /* Support supérieur           */ -    char sel_path;                          /* Chemin à appliquer          */ +    if (node->path == target) +        return true; +    if (node->simple) +        return false; -    //printf(" ============== PATH :: '%c' =======================\n", path[pos]); +    return is_panel_node_matching(node->first, target) +        || is_panel_node_matching(node->second, target); -    part = get_panel_given_part(base, pos, path[pos]); +} -    //printf("-- trouve :: %p ( station ?= %d) ( base ?= %d)\n", part, GTK_IS_DOCK_STATION(part), GTK_IS_DOCK_STATION(base)); +/****************************************************************************** +*                                                                             * +*  Paramètres  : item  = composant à présenter à l'affichage.                 * +*                node  = point d'insertion courant.                           * +*                path  = partie du chemin représentée ici.                    * +*                depth = profondeur du chemin utilisé.                        * +*                                                                             * +*  Description : Place au bon endroit un panneau donné.                       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t depth) +{ +    char div;                               /* Division demandée           */ +    bool horiz;                             /* Traduction en composant     */ +    bool first;                             /* Point d'insertion           */ +    panel_node *new;                        /* Nouveau noeud créé          */ +    panel_node *support;                    /* Noeud d'accueil désigné     */ -    if (GTK_IS_DOCK_STATION(part)) +    if (node->simple)      { +        /* Si on est sur la bonne voie... */ +        if (path[depth] == '\0' || path[depth] == node->path) +        { +            /* Le parcours s'arrête ici ! */ +            if (path[depth] == '\0' || path[depth + 1] == '\0') +                gtk_dock_panel_add_widget(GTK_DOCK_STATION(node->station), +                                          G_EDITOR_ITEM(item)->widget, +                                          G_EDITOR_ITEM(item)->name); +            /* On ne peut aller plus loin, on doit diviser... */ +            else +            { +                div = toupper(path[depth + 1]); +                first = (div == 'E' || div == 'S'); +                horiz = (div == 'W' || div == 'E'); -        path_i = g_panel_item_get_path_at(G_PANEL_ITEM(item), pos); +                switch_panel_node_into_paned(node, horiz, first); -        widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(part), 0); -        other = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); +                new = create_simple_panel_node_for_item(item, path, depth + 1); -        path_o = g_panel_item_get_path_at(other, pos); +                attach_panel_node_to_paned(node, new, !first); -        //printf(" -- path -- '%c' vs '%c'\n", path_i, path_o); +                rebuild_panels_interface(node); +            } -        if (path_i == path_o) -            gtk_dock_panel_add_widget(GTK_DOCK_STATION(part), item->widget, item->name); +        } +        /* On ne peut aller plus loin, on doit diviser... */          else          { -            /* On fait primer le chemin d'importance */ -            if (path_i == 'M' || (isupper(path_o) && !isupper(path_i))) -                sel_path = path_o; -            else -                sel_path = path_i; +            div = toupper(path[depth]); +            first = (div == 'E' || div == 'S'); +            horiz = (div == 'W' || div == 'E'); -            parent = gtk_widget_get_parent(base); -            create_panel_division(parent, item->widget, item->name, base, NULL, sel_path); -        } +            switch_panel_node_into_paned(node, horiz, first); -    } +            new = create_simple_panel_node_for_item(item, path, depth); -    else if (GTK_IS_PANED(part)) -    { +            attach_panel_node_to_paned(node, new, !first); +            rebuild_panels_interface(node); +        } -        printf("Paf Paned !\n"); -        exit(0); +    } +    /* On regarde des autres côtés... */ -    } +    else if (is_panel_node_matching(node->first, path[depth])) +        insert_item_as_panel_node(item, node->first, path, depth + (node->first->simple ? 1 : 0)); -    /* Si on n'a rien trouvé, alors on redivise */ -    else /*if (part == NULL)*/ +    else if (is_panel_node_matching(node->second, path[depth])) +        insert_item_as_panel_node(item, node->second, path, depth + (node->second->simple ? 1 : 0)); + +    /* On doit diviser qqch... */ +    else      { -        if (!GTK_IS_DOCK_STATION(base)) +        /* Si l'élément doit passer en force */ +        if (isupper(path[depth]))          { -            path_i = get_first_path_found(gtk_paned_get_child1(GTK_PANED(base)), pos); -            path_o = get_first_path_found(gtk_paned_get_child2(GTK_PANED(base)), pos); +            div = path[depth]; +            first = (div == 'E' || div == 'S'); +            horiz = (div == 'W' || div == 'E'); -            if (path_i == 'M' || (isupper(path_o) && islower(path_i))) -                base = gtk_paned_get_child1(GTK_PANED(base)); -            else -                base = gtk_paned_get_child2(GTK_PANED(base)); +            switch_panel_node_into_paned(node, horiz, first); -        } +            new = create_simple_panel_node_for_item(item, path, depth); -        path_i = g_panel_item_get_path_at(G_PANEL_ITEM(item), pos); +            attach_panel_node_to_paned(node, new, !first); -        widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); -        other = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); +            rebuild_panels_interface(node); -        path_o = g_panel_item_get_path_at(other, pos); +        } -        /* On fait primer le chemin d'importance */ -        if (path_i == 'M' || (islower(path_i) && isupper(path_o))) -            sel_path = path_o;          else -            sel_path = path_i; - -        //printf(" ++>> DIR :: '%c' vs '%c' => '%c'\n", path[pos], path_o, sel_path); +        { +            if (is_panel_node_matching(node->second, 'M')) +                support = node->second; +            else +                support = node->first; -        parent = gtk_widget_get_parent(base); -        create_panel_division(parent, item->widget, item->name, base, NULL, sel_path); +            div = toupper(path[depth]); +            first = (div == 'E' || div == 'S'); +            horiz = (div == 'W' || div == 'E'); -    } +            switch_panel_node_into_paned(support, horiz, first); +            new = create_simple_panel_node_for_item(item, path, depth); +            attach_panel_node_to_paned(support, new, !first); -} +            rebuild_panels_interface(support); +        } +    } -/* ---------------------------------------------------------------------------------- */ -/*                         PLACEMENTS DES DIFFERENTS PANNEAUX                         */ -/* ---------------------------------------------------------------------------------- */ +}  /******************************************************************************  *                                                                             * -*  Paramètres  : handler = procédure à réveiller en cas de changements.       * -*                data    = donnée à faire suivre.                             * +*  Paramètres  : current = point de départ de la réorganisation graphique.    *  *                                                                             * -*  Description : Prépare le terrain pour l'affichage central.                 * +*  Description : Met à jour l'affichage suite à un changement hiérarchique.   *  *                                                                             * -*  Retour      : Composant de support sur lequel tout va se placer.           * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GtkWidget *init_panels2(GCallback handler, gpointer data) +static void rebuild_panels_interface(const panel_node *current)  { -    GtkWidget *result;                      /* Support à retourner         */ - -    result = qck_create_padded_alignment(0, 0, 0, 0); -    gtk_widget_show(result); - -    _support = result; -    _handler = handler; -    _data = data; +    GtkWidget *widget;                      /* Composant à traiter         */ +    panel_node *parent;                     /* Raccourci confortable       */ -    return result; +    widget = GET_PANEL_NODE_WIDGET(current); -} +    /* On se trouve à la racine... */ +    if (current->parent == NULL) +            gtk_container_add(GTK_CONTAINER(_support), widget); +    /* Sinon, une sous-division ne peut venir que d'une division... */ +    else +    { +        /* BUG_ON(parent->simple) */ -/****************************************************************************** -*                                                                             * -*  Paramètres  : ref = espace de référencement global.                        * -*                                                                             * -*  Description : Charge les principaux panneaux de l'éditeur.                 * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +        parent = current->parent; -void load_main_panels(GObject *ref) -{ -    GPanelItem *item;                       /* Panneau de base à charger   */ +        if (current == parent->first) +            gtk_paned_add1(GTK_PANED(parent->paned), widget); +        else +            gtk_paned_add2(GTK_PANED(parent->paned), widget); -    item = create_log_panel(); -    g_panel_item_dock(item); +    } -    item = create_symbols_panel(ref); -    g_panel_item_dock(item); +    //g_object_unref(G_OBJECT(widget));  } diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h index 893c48b..0dd25a9 100644 --- a/src/gui/panels/panel.h +++ b/src/gui/panels/panel.h @@ -49,7 +49,7 @@ typedef struct _GPanelItemClass GPanelItemClass;  GType g_panel_item_get_type(void);  /* Crée un élément de panneau réactif. */ -GEditorItem *g_panel_item_new(const char *, const char *, GtkWidget *, const char *); +GEditorItem *g_panel_item_new(GObject *, const char *, const char *, GtkWidget *, const char *);  /* Recherche un panneau à partir de son nom court. */  GPanelItem *g_panel_item_get(const char *); diff --git a/src/gui/panels/symbols.h b/src/gui/panels/symbols.h index f18a2ea..182238a 100644 --- a/src/gui/panels/symbols.h +++ b/src/gui/panels/symbols.h @@ -33,7 +33,7 @@ -#define PANEL_SYMBOL_ID _("Symboles") +#define PANEL_SYMBOL_ID _("Symbols")  #define G_TYPE_SYMBOLS_PANEL               g_symbols_panel_get_type() diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c new file mode 100644 index 0000000..018f12a --- /dev/null +++ b/src/gui/panels/welcome.c @@ -0,0 +1,179 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * welcome.c - panneau d'affichage d'accueil + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#include "welcome.h" + + +#include <string.h> +#include <gtk/gtk.h> + + +#include "panel-int.h" +#include "../../gtkext/easygtk.h" +#include "../../gtkext/support.h" + + + +/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ + + +/* Panneau d'aperçu de graphiques (instance) */ +struct _GWelcomePanel +{ +    GPanelItem parent;                      /* A laisser en premier        */ + +}; + + +/* Panneau d'aperçu de graphiques (classe) */ +struct _GWelcomePanelClass +{ +    GPanelItemClass parent;                 /* A laisser en premier        */ + +}; + + +/* Initialise la classe des panneaux d'accueil. */ +static void g_welcome_panel_class_init(GWelcomePanelClass *); + +/* Initialise une instance de panneau d'accueil. */ +static void g_welcome_panel_init(GWelcomePanel *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                            PARTIE PRINCIPALE DU PANNEAU                            */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit pour un panneau d'accueil. */ +G_DEFINE_TYPE(GWelcomePanel, g_welcome_panel, G_TYPE_PANEL_ITEM); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des panneaux d'accueil.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_welcome_panel_class_init(GWelcomePanelClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : panel = instance à initialiser.                              * +*                                                                             * +*  Description : Initialise une instance de panneau d'accueil.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_welcome_panel_init(GWelcomePanel *panel) +{ +    GtkWidget *support;                     /* Fond du panneau             */ +    GtkWidget *align;                       /* Alignement centré           */ +    gchar *filename;                        /* Chemin d'accès au fichier   */ +    GtkWidget *image;                       /* Image chargée               */ +    GEditorItem *base;                      /* Version basique d'instance  */ + +    support = gtk_handle_box_new(); +    gtk_widget_modify_bg(support, GTK_STATE_NORMAL, &support->style->bg[GTK_STATE_NORMAL]); +    gtk_widget_show(support); + +    align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f); +    gtk_widget_show(align); +    gtk_container_add(GTK_CONTAINER(support), align); + +    filename = find_pixmap_file("welcome.png"); +    image = qck_create_image(NULL, NULL, filename); +    gtk_container_add(GTK_CONTAINER(align), image); + +    base = G_EDITOR_ITEM(panel); +    base->widget = support; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencement global.                        * +*                                                                             * +*  Description : Crée un panneau d'accueil.                                   * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GEditorItem *g_welcome_panel_new(GObject *ref) +{ +    GEditorItem *result;                    /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_WELCOME_PANEL, NULL); + +    g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_WELCOME_ID, +                          _("Welcome"), G_EDITOR_ITEM(result)->widget, "M"); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencement global.                        * +*                                                                             * +*  Description : Construit et intègre un panneau d'accueil.                   * +*                                                                             * +*  Retour      : Adresse du panneau mis en place.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GPanelItem *create_welcome_panel(GObject *ref) +{ +    GEditorItem *result;                    /* Elément réactif à renvoyer  */ + +    result = g_welcome_panel_new(ref); + +    /* Enregistre correctement le tout */ +    register_editor_item(result); + +    return G_PANEL_ITEM(result); + +} diff --git a/src/gui/panels/welcome.h b/src/gui/panels/welcome.h new file mode 100644 index 0000000..2bf5002 --- /dev/null +++ b/src/gui/panels/welcome.h @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * welcome.h - prototypes pour le panneau d'affichage d'accueil + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#ifndef _GUI_PANELS_WELCOME_H +#define _GUI_PANELS_WELCOME_H + + +#include <i18n.h> + + +#include "panel.h" + + + +#define PANEL_WELCOME_ID _("Welcome") + + +#define G_TYPE_WELCOME_PANEL               g_welcome_panel_get_type() +#define G_WELCOME_PANEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_welcome_panel_get_type(), GWelcomePanel)) +#define G_IS_WELCOME_PANEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_welcome_panel_get_type())) +#define G_WELCOME_PANEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_WELCOME_PANEL, GWelcomePanelClass)) +#define G_IS_WELCOME_PANEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_WELCOME_PANEL)) +#define G_WELCOME_PANEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_WELCOME_PANEL, GWelcomePanelClass)) + + +/* Panneau d'affichage des symboles (instance) */ +typedef struct _GWelcomePanel GWelcomePanel; + +/* Panneau d'affichage des symboles (classe) */ +typedef struct _GWelcomePanelClass GWelcomePanelClass; + + +/* Indique le type définit pour un panneau d'accueil. */ +GType g_welcome_panel_get_type(void); + +/* Crée un panneau d'accueil. */ +GEditorItem *g_welcome_panel_new(GObject *); + +/* Construit et intègre un panneau d'accueil. */ +GPanelItem *create_welcome_panel(GObject *); + + + +#endif  /* _GUI_PANELS_WELCOME_H */ @@ -149,8 +149,8 @@ int main(int argc, char **argv)      filename = get_string_config_value(config, MPT_LAST_PROJECT); -    if (filename == NULL) project = g_study_project_new(); -    else project = g_study_project_open(filename); +    if (filename == NULL) project = g_study_project_new(G_OBJECT(editor)); +    else project = g_study_project_open(G_OBJECT(editor), filename);      set_current_project(project); diff --git a/src/project.c b/src/project.c index c3c1844..37fc3e5 100644 --- a/src/project.c +++ b/src/project.c @@ -61,6 +61,8 @@ struct _GStudyProject  {      GObject parent;                         /* A laisser en premier        */ +    GObject *ref;                           /* Espace de référencement     */ +      char *filename;                         /* Lieu d'enregistrement       */      loaded_binary **binaries;               /* Fichiers binaires associés  */ @@ -148,12 +150,15 @@ static void g_study_project_init(GStudyProject *project)  *                                                                             *  ******************************************************************************/ -GStudyProject *g_study_project_new(void) +GStudyProject *g_study_project_new(GObject *ref)  {      GStudyProject *result;                  /* Composant à retourner       */      result = g_object_new(G_TYPE_STUDY_PROJECT, NULL); +    g_object_ref(ref); +    result->ref = ref; +      return result;  } @@ -171,7 +176,7 @@ GStudyProject *g_study_project_new(void)  *                                                                             *  ******************************************************************************/ -GStudyProject *g_study_project_open(const char *filename) +GStudyProject *g_study_project_open(GObject *ref, const char *filename)  {      GStudyProject *result;                  /* Adresse à retourner         */      xmlDocPtr xdoc;                         /* Structure XML chargée       */ @@ -184,7 +189,7 @@ GStudyProject *g_study_project_open(const char *filename)      if (!open_xml_file(filename, &xdoc, &context)) return NULL; -    result = g_study_project_new(); +    result = g_study_project_new(ref);      result->filename = strdup(filename); @@ -405,7 +410,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina      scroll = loaded->scrollwindows[BVW_BLOCK];      title = g_loaded_binary_get_filename(binary, false); -    loaded->item = g_panel_item_new(title, title, scroll, "M"); +    loaded->item = g_panel_item_new(project->ref, title, title, scroll, "M");      /* Enregistrement dans le projet */ diff --git a/src/project.h b/src/project.h index de5badb..0665ec0 100644 --- a/src/project.h +++ b/src/project.h @@ -67,10 +67,10 @@ typedef struct _GStudyProjectClass GStudyProjectClass;  GType g_study_project_get_type(void);  /* Crée un nouveau projet vierge. */ -GStudyProject *g_study_project_new(void); +GStudyProject *g_study_project_new(GObject *);  /* Crée un projet à partir du contenu XML d'un fichier. */ -GStudyProject *g_study_project_open(const char *); +GStudyProject *g_study_project_open(GObject *, const char *);  /* Procède à l'enregistrement d'un projet donné. */  bool g_study_project_save(GStudyProject *, const char *); | 
