GTK+ par l'exemple


précédentsommairesuivant

X. Fermer

X-A. Aperçu

Image non disponible
Cliquez pour agrandir

X-B. Fermer un fichier

Maintenant que nous allouons de la mémoire, il faut la libérer à un endroit. Logiquement cela va être fait à la fermeture du document, en guise d'exercice, je vous laisse créer le bouton dans notre boîte à bouton...
...
Allez je vous aide, le stock id correspondant est GTK_STOCK_CLOSE.
Voilà maintenant, si tout c'est bien passé, vous devriez être arrivé dans le fichier callback.c avec quelque chose ressemblant à :

callback.c
Sélectionnez
void cb_close (GtkWidget *p_widget, gpointer user_data)
{
  /* ... */
}

Lorsque l'on ferme un document, il faut vider le GtkTextView (avec les onglets, on se contentera de le supprimer), pour cela, il faut récupérer le début et la fin du GtkTextBuffer et demander à GTK+ de supprimer tout ce qui ce trouve entre les deux itérateurs :

callback.c
Sélectionnez
  /* Avant de fermer, il faut verifier qu'un document a bien ete ouvert */
  if (docs.actif)
  {
    GtkTextIter start;
    GtkTextIter end;
    GtkTextBuffer *p_text_buffer = NULL;

    p_text_buffer = gtk_text_view_get_buffer (docs.actif->p_text_view);
    gtk_text_buffer_get_bounds (p_text_buffer, &start, &end);
    gtk_text_buffer_delete (p_text_buffer, &start, &end);
    /* ... */
  }
  else
  {
    print_warning ("Aucun document ouvert");
  }

Bien sûr il ne faut pas oublier de libérer la mémoire 

callback.c
Sélectionnez
    g_free (docs.actif->chemin), docs.actif->chemin = NULL;
    docs.actif->p_text_view = NULL;
    g_free (docs.actif), docs.actif = NULL;

Pour symboliser la fermeture d'un document, nous désactivons le GtkTextView lors de la fermeture (ne pas oublier de le faire aussi dans main.c) :

callback.c
Sélectionnez
    gtk_widget_set_sensitive (GTK_WIDGET (docs.actif->p_text_view), FALSE);

Et nous le réactivons lors de l'ouverture si celle si réussie :

callback.c
Sélectionnez
    gtk_widget_set_sensitive (GTK_WIDGET (docs.actif->p_text_view), TRUE);

Lorsque l'utilisateur quitte l'application, il faut bien sûr fermer le document, s'il y en a un ouvert :

 
Sélectionnez
void cb_quit (GtkWidget *p_widget, gpointer user_data)
{
  if (docs.actif)
  {
    cb_close (p_widget, user_data);
  }
  gtk_main_quit();
}

Et aussi lorsqu'il créé un nouveau document (et par conséquent lorsqu'il ouvre un fichier puisque l'on fait appel à cb_new) :

 
Sélectionnez
void cb_new (GtkWidget *p_widget, gpointer user_data)
{
  if (docs.actif)
  {
    cb_close (p_widget, user_data);
  }
  /* ... */
}

X-C. Enregistrer avant de fermer

Si le document a été modifié depuis la dernière sauvegarde, généralement le programme le signale à l'utilisateur et lui propose de sauvegarder ou d'annuler la fermeture. Pour se faire, nous devons modifier la fonction cb_close, avant de fermer le document, nous allons afficher une boîte de dialogue.
Pour créer une boîte de dialogue simplement, il existe la classe GtkDialog et comme nous avons besoin de boutons (pour que l'utilisateur fasse son choix), nous allons créer notre boîte avec la fonction :

 
Sélectionnez
GtkWidget *gtk_dialog_new_with_buttons (const gchar *title, GtkWindow *parent, GtkDialogFlags flags, const gchar *first_button_text, ...);

Nous retrouvons les mêmes options que pour le GtkFileChooserDialog, mis à part option du type GtkDialogFlags :

 
Sélectionnez
typedef enum
{
  GTK_DIALOG_MODAL               = 1 << 0, /* appel gtk_window_set_modal (win, TRUE) */
  GTK_DIALOG_DESTROY_WITH_PARENT = 1 << 1, /* appel gtk_window_set_destroy_with_parent () */
  GTK_DIALOG_NO_SEPARATOR        = 1 << 2  /* Pas de barre de separation au dessus des boutons */
} GtkDialogFlags;

Nous nous contenterons de rendre notre fenêtre modale (7).
Pour avoir accès à notre fenêtre principale, nous ajoutons un champs p_main_window à notre structure globale docs_t que nous initialisons dans la fonction main :

main.c
Sélectionnez
  docs.p_main_window = GTK_WINDOW (p_window);

Il nous reste plus qu'a créer notre boîte de dialogue avec trois boutons : Oui, Non, Annuler :

callback.c
Sélectionnez
    if (!docs.actif->sauve)
    {
      GtkWidget *p_dialog = NULL;

      p_dialog = gtk_dialog_new_with_buttons ("Sauvegarder",
                                              docs.p_main_window,
                                              GTK_DIALOG_MODAL,
                                              GTK_STOCK_YES, GTK_RESPONSE_YES,
                                              GTK_STOCK_NO, GTK_RESPONSE_NO,
                                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
      /* ... */

Nous obtenons donc une structure de type GtkDialog :

 
Sélectionnez
typedef struct {
  GtkWidget *vbox;
  GtkWidget *action_area;
} GtkDialog;

Nous remarquons que cette structure contient deux membres qui permettent d'accéder à une GtkBox, où nous allons ajouter le contenu de la fenêtre, et à la partie contenant les boutons.
Ensuite la construction de la fenêtre est identique à celle de la fenêtre principale, ici nous nous contenterons d'ajouter un GtkLabel :

callback.c
Sélectionnez
      GtkWidget *p_label = NULL;
      /* ... */
      p_label = gtk_label_new ("Voulez-vous sauvegarder les modifications ?");
      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (p_dialog)->vbox), p_label, TRUE, TRUE, 0);

Une fois notre fenêtre prête, il suffit de faire appel à la fonction gtk_dialog_run qui va afficher notre GtkDialog et nous retourner le réponse id correspondant au bouton cliqué par l'utilisateur :

callback.c
Sélectionnez
      switch (gtk_dialog_run (GTK_DIALOG (p_dialog)))
      {
        case GTK_RESPONSE_YES:
          cb_save (p_widget, user_data);
        break;
        case GTK_RESPONSE_NO:
        break;
        case GTK_RESPONSE_CANCEL:
          gtk_widget_destroy (p_dialog);
          return;
        break;
      }
      gtk_widget_destroy (p_dialog);
    }
    /* ... */

Si l'utilisateur clique sur non, on ne fait rien (le document sera simplement fermé), sur oui, on enregistre avant de fermer et pour finir, s'il annule on quitte la fonction.

X-D. Code source


précédentsommairesuivant
Une boîte de dialogue modale empêche l'utilisateur d'interagir avec sa fenêtre parent

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

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 et 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.