IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

GTK+ par l'exemple


précédentsommairesuivant

VII. Interlude

Avant d'aller plus loin dans l'amélioration de l'interface de notre éditeur, il est nécessaire de modifier son fonctionnement interne (ne vous inquiétez je n'ai pas dit chambouler), en effet, souvenez-vous dans l'introduction j'ai évoqué la possibilité d'ouvrir plusieurs documents grâce à un système d'onglets. Pour cela, il faut sauvegarder les propriétés de chaque document ouvert. Pris à temps ce genre de modification n'est pas trop lourde, mais si nous attendons, cela risque de devenir un vrai casse-tête !
Pour cela nous allons utiliser une structure de donnée pour chaque document ouvert qui devra garder en mémoire le chemin complet du fichier (ou NULL si le document n'est pas encore sauvegarder), s'il a été modifié depuis la dernière sauvegarde et le GtkTextView qui sert à son affichage. Voici donc la structure qui va nous servir :

document.h
Sélectionnez
typedef struct
{
  gchar *chemin;
  gboolean sauve;
  GtkTextView *p_text_view;
} document_t;

Sachant que nous serons amenés à stocker plusieurs occurrences de cette structure, il serait bon de réfléchir dès maintenant à la structure de donnée à utiliser pour les stocker. La première idée qui vient à l'esprit est un tableau alloué dynamiquement, cependant l'utilisateur peut souhaiter fermer un document qui se trouve au milieu, on est alors obligé de décaler toutes les cellules en amont. Dans ce cas il parait naturel d'utiliser une liste chaînée. Par chance la glib propose une bibliothèque de gestion des listes chaînées, cela nous fera gagner du temps le moment venu. Pour l'instant, on se contente de créer une structure de données qui contiendra tous les documents ouverts (stockée dans une GList) et un pointeur sur le document actif (actuellement comme nous n'avons qu'un document ouvert en même temps, on manipulera uniquement ce pointeur) :

document.h
Sélectionnez
typedef struct
{
  GList *tous;
  document_t *actif;
} docs_t;

Maintenant se pose le problème de savoir comment transmettre cette structure. On pourrait se servir du paramètre user_data présent dans toutes les fonctions colback, mais certaines fonctions utilisent déjà ce paramètre (la fonction cb_open par exemple), il faudrait créer un champ supplémentaire dans notre structure documents_s. Une solution plus simple est de créer une variable globale à l'ensemble du programme. Ceux qui passent régulièrement sur le forum C savent que c'est fortement déconseillé, mais ici nous nous trouvons dans l'une des rares exceptions à la règle. De toute façon cela revient au même que de passer l'adresse de notre structure à toutes les fonctions callback. Nous définissons donc un nouveau fichier d'en-tête :

document.h
Sélectionnez
#ifndef H_DOCUMENT
#define H_DOCUMENT

#include <gtk/gtk.h>

typedef struct
{
  gchar *chemin;
  gboolean sauve;
  GtkTextView *p_text_view;
} document_t;

typedef struct
{
  GList *tous;
  document_t *actif;
} docs_t;

extern docs_t docs;

#endif /* not H_DOCUMENT */

Et dans le fichier main.c :

main.c
Sélectionnez
#include "document.h"

docs_t docs = {NULL, NULL};

Pour l'instant la seule fonction qui modifie l'état d'un document est la fonction open_file, il faut donc inclure document.h dans callback.c et modifier légèrement la fonction pour enregistrer le document ouvert :

callback.c
Sélectionnez
    if (g_file_get_contents (file_name, &contents, NULL, NULL))
    {
      /* Pour l'instant il faut allouer la memoire, par la suite on modifira
         simplement le pointeur */
      docs.actif = g_malloc (sizeof (*docs.actif));
      docs.actif->chemin = g_strdup (file_name);
      /* Pour l'instant, on se contente de stocker le seul GtkTextView qui existe,
        par la suite, il faudra en creer un nouveau ! */
      docs.actif->p_text_view = p_text_view;
      /* Le document vient d'etre ouvert, il n'est donc pas modifie */
      docs.actif->sauve = TRUE;
      /* ... */
    }

Ne soyez pas choqué si je ne teste pas le retour de la fonction g_malloc pour vérifier qu'il n'est pas NULL. En effet, cette dernière met fin à l'application si l'allocation échoue.

VII-A. Code source


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006-2008 Nicolas Joseph. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.