Accueil
Accueil Le Club Delphi Kylix C C++ Java J2EE DotNET & C# Visual Basic Access Pascal Dev Web PHP ASP XML UML SQLSGBD Windows Linux Autres

GTK+ par l'exemple

Date de publication : 28 juin 2006




VIII. Sauvegarder les modification
VIII-A. Aperçu
VIII-B. Enregistrer
VIII-C. Enregistrer sous
VIII-D. Code source


VIII. Sauvegarder les modification


VIII-A. Aperçu

Cliquez pour agrandir

VIII-B. Enregistrer

Avant de pouvoir sauvegarder un document, il faut qu'il soit modifié. Comment savoir que le contenu du fichier a été modifier ? Grâce au signal changed du GtkTextBuffer que nous interceptons grâce à la fonction cb_modifie :
main.c
  {
    GtkTextBuffer *p_text_buffer = NULL;

    p_text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (p_text_view));
    g_signal_connect (G_OBJECT (p_text_buffer), "changed", G_CALLBACK (cb_modifie), NULL);
  }
Cette dernière modifie simplement le champ sauve du document :
callback.c
void cb_modifie (GtkWidget *p_widget, gpointer user_data)
{
  if (docs.actif)
  {
    docs.actif->sauve = FALSE;
  }
}
Pour la sauvegarde, il faut distinguer deux cas : soit il s'agit de la première sauvegarde du fichier, il faut alors demander le nom du fichier à l'utilisateur (cela ressemble fortement à l'ouverture d'un fichier), soit le fichier est déjà présent sur le disque, il suffit de remplacer son contenu par celui du GtkTextViewer. Nous avons convenu qu'un fichier qui n'était pas encore enregistré avait sa propriété chemin à NULL.
Bien sûr cela n'a lieu que si un fichier est ouvert et qu'il a été modifié depuis sa dernière sauvegarde :
callback.c
void cb_save (GtkWidget *p_widget, gpointer user_data)
{
  if (docs.actif)
  {
    if (!docs.actif->sauve)
    {
      /* Le fichier n'a pas encore ete enregistre */
      if (!docs.actif->chemin)
      {
        GtkWidget *p_dialog = NULL;

        p_dialog = gtk_file_chooser_dialog_new ("Sauvegarder le fichier", NULL,
                                                GTK_FILE_CHOOSER_ACTION_SAVE,
                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                                GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                                NULL);
        if (gtk_dialog_run (GTK_DIALOG (p_dialog)) == GTK_RESPONSE_ACCEPT)
        {
          docs.actif->chemin = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (p_dialog));
        }
        gtk_widget_destroy (p_dialog);
      }
      /* Soit le fichier a deja ete enregistre, soit l'utilisateur vient de nous
         fournir son nouvel enplacement, on peut donc l'enregistrer */
      if (docs.actif->chemin)
      {
        /* ... */
      }
    }
  }
  else
  {
    print_warning ("Aucun document ouvert");
  }
}
Il nous reste plus qu'à récupérer le contenu du GtkTextViewer et le copier dans le fichier chemin sans oublier de reconvertir le texte dans le codage local :
callback.c
        FILE *fichier = NULL;

        fichier = fopen (docs.actif->chemin, "w");
        if (fichier)
        {
          gchar *contents = NULL;
          gchar *locale = NULL;
          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);
          contents = gtk_text_buffer_get_text (p_text_buffer, &start, &end, FALSE);
          locale = g_locale_from_utf8 (contents, -1, NULL, NULL, NULL);
          g_free (contents), contents = NULL;
          fprintf (fichier, "%s", locale);
          g_free (locale), locale = NULL;
          fclose (fichier), fichier = NULL;
          docs.actif->sauve = TRUE;
        }
        else
        {
          print_warning ("Impossible de sauvegarder le fichier %s", docs.actif->chemin);
        }
Le dernier paramètre de la fonction gtk_text_buffer_get_text est mis à FALSE car nous ne voulons pas enregistrer les caractères invisibles présent dans le GtkTextBuffer. Ces caractères servent à mettre en forme le texte (taille, couleur...), nous pourrions créer un nouveau format de fichier pour enregistrer la mise en forme.


VIII-C. Enregistrer sous

Pour enregistrer notre document sous un autre nom, il suffit de faire croire à cb_save que le document n'a pas encore était enregistré, tout simplement en changeant chemin à NULL et sauve à FALSE :
callback.c
void cb_saveas (GtkWidget *p_widget, gpointer user_data)
{
  if (docs.actif)
  {
    document_t tmp = *docs.actif;

    docs.actif->chemin = NULL;
    docs.actif->sauve = FALSE;
    cb_save (p_widget, user_data);
    if (!docs.actif->sauve)
    {
      (*docs.actif) = tmp;
    }
  }
  else
  {
    print_warning ("Aucun document ouvert");
  }
}
Il ne faut pas oublier que l'utilisateur peut annuler l'enregistrement, de ce fait, nous sauvegardons l'état du document et si la sauvegarde n'a pas eu lieu, on le restaure.


VIII-D. Code source




 

Les sources présentés sur cette pages sont libre de droits, et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright ©2006 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérets. Cette page est déposée à la SACD.

Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels, cours et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones. Nous contacter - Copyright 2000..2005 www.developpez.com