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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

IT-Edit (Integrated Terminal Editor).


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut IT-Edit (Integrated Terminal Editor).
    Salut les GTK,
    je vient vous présenter ma dernière création, IT-Edit un éditeur de texte avec de multiples fonctionnalités. Créer avec GTK+3, gtksourceview3.0 et libvte.

    Motivation pour l'écriture de IT-Edit (the Integrated Terminal Editor).

    Ont peut diviser les programmeurs selon leur façon de travailler en 2 catégories:

    * Ceux qui utilisent un IDE: un environnement de développement complet.

    * Ceux qui travaillent avec des outils séparés: un éditeur de texte, usage du terminal et autres outils.

    Comme je suis un programmeur de la deuxième catégorie et comme j'ai remarquer que j’utilisais souvent un client internet pour la doc HTML offline.

    J'ai décidé d'écrire mon propre éditeur de texte qui me donne un accès directe a tous les outils dont j'ai besoin.

    De cette idée est née IT-Edit.

    Fonctionnalités de IT-Edit

    IT-Edit implémente un éditeur de texte avec colorations syntaxique, affichage des numéros de lignes et la complétion automatique avec les fonctionnalités de base d'un éditeur de texte:

    * Couper / Copier / Coller.

    * Dupliquer la sélection ou de la ligne du curseur.

    * Undo/Redo.

    * Aller a une ligne donnée.

    * Recherche et remplacement.

    Pour la gestion de fichiers IT-Edit implémente:

    * Ouvrir un fichier vierge.

    * Ouvrir un fichier donnée.

    * Ouvrir un fichier récent.

    * Sauvegarder le contenus de l'éditeur.

    * Sauvegarder le contenus de l'éditeur dans un fichier choisis.

    * Sauvegarder tous les fichiers ouverts.


    Il existe évidemment des raccourcis clavier pour ces fonctionnalités.

    IT-Edit implémente 2 terminaux dans la fenêtre principale qui sont aisément déployables, repliables et peuvent être redimensionnées.

    IT-Edit implémente une fonctionnalité pour exécuter une commande quelqu'onque dans un terminal dans une fenêtre toplevel qui est facilement maximisable, minimisable et redimensionnable.

    NOTE: cette fonctionnalité était prévus pour la visualisation de manpages qui a été étendue a toutes sortes de commandes, sans restriction.

    IT-Edit implémente un mécanisme d'enregistrement de fichiers quelquonque (doc html, pdf, ps ou musique, vidéo...)
    un accès directe a tous les outils dont j'ai besoin
    Qui seront après enregistrement lançable par le programme par défaut associé au type de fichier.

    NOTE: cette fonctionnalités était prévus pour la visualisation de documentation offline HTML qui a été étendus.

    Avec ses terminaux intégré IT-Edit vous fournis une environnement de développement, répondant a tout vos besoin.

    Prenez la peine d'essayer de s'habituer a IT-Edit, vous allez sûrement l'adopter.

    Le programme est distribuer sous forme de paquetage *.deb, si cela ne vous convient pas allez dans:
    Programmes->Accéder a l'index->C->IT-Edit, vous y trouverez un tarball compatible Linux et BSD (non-testé).
    Pour installer IT-Edit tapez:

    $ ./configure
    $ make
    $ sudo make install

    Je suis ouvert a toute formes de critiques, si vous avez des commentaires a faire sur le code, les fonctionnalités auquelles je n'ai pas penser etc...

    PS: J'ai vraiment écrit ce pseudo IDE pour mes propres besoins, mais je tiens a vous en faire profiter, quand même, afin qu'il évolue selon les fondements du free-software.

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut Test
    Je vais y jeter un œil...ou deux

    Voila mes premières constatations :

    • L'installation sur une Debian SID s'est passée sans aucun problème.
    • Je retrouve le lien de l'éditeur dans le menu "Développement" de XFCE, nickel !


    Je lance l'éditeur. Tout fonctionne bien. C'est déjà un bon point. Tu utilises des boutons et des menus avec des icônes. Cela ne me gêne pas du tout mais c'est en voie de disparition. Gtk+ ne le permet plus directement dans ses dernières versions.

    J'ai ouvert la fenêtre des terminaux. Deux terminaux ouverts, je trouve ca bien. Il m'arrive très souvent aussi d'avoir besoin de deux terminaux, surtout lorsque je code une bibliothèque. J'aurais par contre aimé que les terminaux s'ouvrent dans le répertoire du fichier que j'ai ouvert précédemment. Idem pour le bouton "Cmd". J'ai ouvert un projet constuit avec les autotools. Une fois fait j'ai cliqué sur "Cmd" et tapé "make". Je m'attendais à ce que la commande s'effectue dans le répertoire du projet.

    Code source :


    J'ai juste ouvert it-edit.c. Tu vas pouvoir travailler ton code selon deux axes :

    1. regarde la Glib. Tu as toutes les fonctions nécessaires pour te passer de asprintf, fprintf...Ainsi tu pourras limiter l'appel à des bibliothèques externes (même si certaines sont déjà appelées par la Glib),
    2. je ne vois nulle part l'utilisation de Glade. Ou je n'ai pas les yeux en face des trous ou c'est bien le cas. Penche-toi sur cet outil, tu pourras alors alléger ton code de manière drastique.


    Voila pour mes premières impressions. Je te félicite pour ce joli travail.

  3. #3
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci vraiment beaucoup pour ces encouragements, commentaires, impressions et compliments.

    J'ai pas mal travailler sur le code après que le programme soit complètement fonctionnel, afin de ne pas faire d'appels inutiles, ce que j'ai beaucoup fait en cours de développement. a voir ici.

    Tu utilises des boutons et des menus avec des icônes. Cela ne me gêne pas du tout mais c'est en voie de disparition. Gtk+ ne le permet plus directement dans ses dernières versions.
    D'accord mais alors qu'est-ce qui est "a la mode" alors ?

    Personnellement je tourne sur une Ubuntu LTS donc je n'ai pas la dernière version de GTK+3: les rollings releases fournissent sûrement des version plus récentes de GTK+3.




    Concernant le répertoire courant des terminaux leurs initialisation permet de définir un répertoire courant.

    J'ai penser que l'on pouvait se déplacer dans les répertoires puis de lancer sa commande puis une autre, puis une autre. le répertoire courant ne change pas sauf si vous quittez l'application.

    Et sauf pour le bouton Cmd qui lance a chaque fois un nouveau terminal dans le répertoire $HOME de l'utilisateur.

    Pour pallier a ce problème il y a deux solutions:

    1) Soit simplement garder le terminal (Cmd) ouvert et se placer là ou l'on veut. Idem pour les terminaux intégrés.

    2) Soit mettre les mains dans le cambouis et ajouter un pointeur de type char dans la structure Settings et l'initialiser avec la fonction de libvte2_90:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char *vte_terminal_get_current_directory_uri(VteTerminal *terminal) ;
    En quittant le programme ou a chaque changement de répertoire avec le signal:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "current-directory-uri-changed"
    Et au nouveau démarrage ou lors de l'appui sur Cmd initialiser le terminal avec la valeur enregistrer auparavant, grâce a la fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    gboolean vte_terminal_fork_command_full(VteTerminal *terminal,
                                                             VtePtyFlags pty_flags,
                                                             const char *working_directory,
                                                             char **argv,
                                                             char **envv,
                                                             GSpawnFlags spawn_flags,
                                                             GSpawnChildSetupFunc child_setup,
                                                             gpointer child_setup_data,
                                                             GPid *child_pid,
                                                             GError **error);
    Note: Ça parait compliqué comme prototype mais beaucoup de paramètres peuvent être mis a NULL.

    Libre a vous de modifier, a votre guise, le programme comme dit par la licence GPLv3 l'accompagnant...


    D'ailleurs je l'ai distribuer dans ce but afin de vous fournir une base pour construire votre environnement de travail a vous.

    Car qui maîtrise le mieux un éditeur que celui qui l'a conçus.


    regarde la Glib. Tu as toutes les fonctions nécessaires pour te passer de asprintf, fprintf...Ainsi tu pourras limiter l'appel à des bibliothèques externes (même si certaines sont déjà appelées par la Glib),
    Je vais regarder, merci.

    Il est vrai que l'appel a l'extension GNU asprintf() réduit le nombre d'utilisateur potentiels mais cela m'importe peu, même si ça me gêne aussi d'utiliser une fonction qui ne soit pas complètement standard. (asprintf() est présent sur BSD aussi.)

    je ne vois nulle part l'utilisation de Glade. Ou je n'ai pas les yeux en face des trous ou c'est bien le cas. Penche-toi sur cet outil, tu pourras alors alléger ton code de manière drastique.
    Je n'ai pas utiliser Glade, effectivement mais j'ai implémenter une fonction de setup pour chaque composante de l'interface, enfin presque: menu, buttonbox, terminaux...

    Je préfère travailler en dur, même si le code s'en trouve largement alourdis, j'y viendrai peut-être a Glade,
    ce n'est que mon deuxième programme en C avec GTK+3 et python est toujours bloquer a GTK+2.

    Je te félicite pour ce joli travail.
    Merci ça fait vraiment chaud au cœur.

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    En regardant un peu tous tes fichiers sources je me suis arrêté sur editor.c.

    Dans la fonction add_file_to_editor(); :

    • Tu utilises les mots réservés bool, false et true. Compiles-tu en C++ ?
    • Tu utilises un pointeur GError. Si la fonction g_file_fet_contents(); retourne FALSE tu ne libères pas l'espace alloué par ce pointeur (avec g_error_free();).
    • Toujours au sujet de GError tu utilises g_strdup_printf(); pour afficher le message d'erreur. Tout d'abord c'est inutile de l'utiliser pour afficher le message et en plus tu as aussi une fuite mémoire à cette occasion, puisque g_strdup_printf(); alloue dans le tas.
    • Attention ! g_locale_to_utf8(); alloue dans le tas. Lorsque tu initialises file_content avec g_file_get_contents(); il pointe sur un espace alloué dans le tas. Écrire ensuite file_content = g_locale_to_utf8 (file_content,...); te fait perdre le pointeur sur la première allocation. Une fuite de plus .


    J'arrête là ma lecture pour le moment. Je regarderai d'autres fichiers quand le temps me le permettra .

  5. #5
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut Merci beaucoup pour votre intérêt porter au code source de IT-Edit
    Merci beaucoup pour votre intérêt porter au code source de IT-Edit,

    Tu utilises les mots réservés bool, false et true. Compiles-tu en C++ ?
    Non pas du tout ce sont des types C99 du fichier stdbool.h, qui implémentent le type booléen.
    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    include <stdbool.h>
     
    bool bool_value = true ;
    Tu utilises un pointeur GError. Si la fonction g_file_get_contents(); retourne FALSE tu ne libères pas l'espace alloué par ce pointeur (avec g_error_free().
    ET bien il s'avère que je ne savait pas qu'il fallait que je libère les variables de type GError.
    Ce n'est pas évident car on déclare un pointeur de type GError statiquement et qu'après on donne l'adresse de ce pointeur a une fonction g_* qui, elle donc alloue de l'espace dynamiquement. Je n'ai pas remarquer.

    Et il est vrai que j'ai oublier de libérer la variable file_content en cas d'echec de g_file_get_content().
    Chose qui devrai pas se produire souvent, a moins d'une erreur de manipulation, comme ouvrir une fichier exécutable dans l'éditeur par mégarde, se produise.

    Toujours au sujet de GError tu utilises g_strdup_printf(); pour afficher le message d'erreur. Tout d'abord c'est inutile de l'utiliser pour afficher le message et en plus tu as aussi une fuite mémoire à cette occasion, puisque g_strdup_printf(); alloue dans le tas.
    Vous avez totalement raison il suffit de passer error->message comme message secondaire de la fenêtre d'erreur.




    Note: Il y a la même fuite de mémoire avec g_strdup_printf() dans le fichier: /Callbacks/search_settings_callbacks.c
    Mais dans ce cas je suis obliger de formater le message.
    Et comme la fenêtre de message d'erreur est détruite par une fonction de timeout je ne peut que lui passer la variable de type GtkWidget *message_dialog comme argument afin que le callback détruise la fenêtre de message d'erreur.
    J'ai bien essayer de faire autrement en déclarant une structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct {
      char *error_message ;
      GtkWidget *error_msg_dialog ;
    } Error_message ;
    Afin de pouvoir:
    *) Libérer le message (car il faut libérer le string retourner par g_strdup_printf())
    *) Détruire la fenêtre de message d'erreur.
    Mais malheureusement cela faisait crasher l'application pendant les assertions (Regardez du coté About->Readme dans la section "Notes for C programmers", il y a un mot sur les 2 fonctions de débogage).
    J'ai préférer avoir une petite fuite au lieu d'un crash de l'application.


    Attention ! g_locale_to_utf8(); alloue dans le tas. Lorsque tu initialises file_content avec g_file_get_contents(); il pointe sur un espace alloué dans le tas. Écrire ensuite file_content = g_locale_to_utf8 (file_content,...); te fait perdre le pointeur sur la première allocation.
    Il va falloir que j'utilise une nouvelle variable pour le retour de g_locale_to_utf8() ;


    Encore grand merci pour l'intérêt porté au code source de IT-Edit.
    Car je n'ai personne pour me relire ou me corriger, je suis tout seul, heureusement qu'il existe des forums et des gens qui s'intéresse a ce que je fait, pour cela.
    Sinon les erreurs détecter resterai non-corriger.

    Je vais corriger ces erreurs dès que vous aurez finit avec les autres fichiers afin de uploader une version corriger sur le serveur.

    Je tiens a vous cité comme correcteur dans les README, alors contacter moi si vous voulez que votre vrai nom y apparaisse ou si vous ne voulez pas être cité.

  6. #6
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    Merci beaucoup pour votre intérêt porter au code source de IT-Edit,



    Non pas du tout ce sont des types C99 du fichier stdbool.h, qui implémentent le type booléen.
    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    include <stdbool.h>
     
    bool bool_value = true ;
    OK, au temps pour moi .

    Citation Envoyé par Luke spywoker Voir le message
    Note: Il y a la même fuite de mémoire avec g_strdup_printf() dans le fichier: /Callbacks/search_settings_callbacks.c
    Mais dans ce cas je suis obliger de formater le message.
    Et comme la fenêtre de message d'erreur est détruite par une fonction de timeout je ne peut que lui passer la variable de type GtkWidget *message_dialog comme argument afin que le callback détruise la fenêtre de message d'erreur.
    J'ai bien essayer de faire autrement en déclarant une structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct {
      char *error_message ;
      GtkWidget *error_msg_dialog ;
    } Error_message ;
    Afin de pouvoir:
    *) Libérer le message (car il faut libérer le string retourner par g_strdup_printf())
    *) Détruire la fenêtre de message d'erreur.
    Mais malheureusement cela faisait crasher l'application pendant les assertions (Regardez du coté About->Readme dans la section "Notes for C programmers", il y a un mot sur les 2 fonctions de débogage).
    J'ai préférer avoir une petite fuite au lieu d'un crash de l'application.

    Il faut voir les choses autrement. Si tu es dans l'obligation de passer un pointeur sur un espace mémoire alloué dans le tas à une fonction et que tu dois libérer cet espace mémoire une fois transmise, il te suffit de modifier la fonction appelée.
    Dans la fonction display_message_dialog(); recopie les chaînes de caractère recues. Tu te retrouves alors dans cette fonction avec des pointeurs pointant sur d'autres espaces mémoires que ceux transmis. La fonction appelante peut alors libérer ses propres pointeurs sans pour autant affecter la fonction appelée.

    Voila le code modifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    GtkWidget  *display_message_dialog(gint message_type, const gchar *message, const gchar *secondary_message, gint buttons)  {
      /** Return a message dialog according to the given arguments. **/
     
      // Recopie des chaînes de caractère
      gchar *message_one = g_strdup (message);
      gchar *message_two = g_strdup (secondary_message);
     
      GtkWidget *message_dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
                                                               message_type,     /** GTK_MESSAGE_INFO || GTK_MESSAGE_ERROR  **/
                                                               buttons,          /** GTK_BUTTONS_NONE || GTK_BUTTONS_CLOSE  **/  
                                                               message_one, NULL);
     
      if (message_two) {
        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(message_dialog), message_two, NULL) ;
      }
     
      return message_dialog ;
    }
    Maintenant tu peux faire appel à cette fonction et libérer derrière les chaînes transmises.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     /** Display an error message dialog in case th term is not found. **/
     
    gchar *message = g_strdup_printf("Pattern:\n\" %s \"\nnot found in file !", searching.search_text);
     
    GtkWidget *not_found_message_dialog = display_message_dialog(GTK_MESSAGE_ERROR, "Pattern not found !!!", message, GTK_BUTTONS_NONE) ;
     
    g_free (message);
    Intellectuellement c'est plus propre. Tu alloues, tu transmets, tu libères. Il ne reste plus que le problème de libération des deux nouveaux espaces alloués. Vu que tu as l'air de bien maîtriser le passage de données via les fonctions g_obect_set_data(); et g_object_get_data(); pourquoi ne pas attacher les deux nouveaux pointeurs message_one et message_two à la nouvelle fenêtre créée ?
    Ainsi, lors de l'appel à destroy_dialog(); tu les récupères et les libères dans la foulée.

    Toute cette explication est faite pour te montrer la philosophie générale à suivre tant que faire ce peut lors de l'allocation dans le tas. Pour ton code, si tu appelles display_message_dialog(); toujours de la même manière tu peux la conserver telle qu'elle. Il te suffit simplement de reprendre le code çi-dessus avec l'allocation du pointeur message, sa transmission et sa libération. Ca devrait fonctionner sans problème puisque gtk_dialog_new(); recopie lui aussi les chaînes transmises.

Discussions similaires

  1. Integration d'un EMF Editor(Plugin) dans une RCP application
    Par UniKa dans le forum Eclipse Platform
    Réponses: 0
    Dernier message: 20/06/2009, 03h44
  2. Integrer visual editor
    Par allia007 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 28/12/2008, 21h48
  3. Réponses: 0
    Dernier message: 08/09/2008, 13h46
  4. Edition d'un objet en BdD : Editor ou View ?
    Par Teocali dans le forum Eclipse Platform
    Réponses: 2
    Dernier message: 12/06/2007, 14h23
  5. [Concours] Le SMILEY d'or - edition aout 2005 terminée
    Par Superstivix dans le forum Jeux
    Réponses: 5
    Dernier message: 31/08/2005, 09h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo