diff options
Diffstat (limited to 'src/glibext/gcodebuffer.c')
-rw-r--r-- | src/glibext/gcodebuffer.c | 806 |
1 files changed, 778 insertions, 28 deletions
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 1d4e6cd..f3634f0 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -32,6 +32,7 @@ #include "chrysamarshal.h" #include "delayed-int.h" +#include "../common/extstr.h" @@ -148,11 +149,28 @@ static void on_line_content_change(GBufferLine *, GBufferSegment *, GCodeBuffer /* Réagit à un changement de propriété rattachée à une ligne. */ static void on_line_flag_flip(GBufferLine *, BufferLineFlags, BufferLineFlags, GCodeBuffer *); -/* Ajoute une nouvelle ligne à une position donnée. */ -static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *, size_t, const mrange_t *); +/* Ajoute de nouvelles lignes à une position donnée. */ +static void g_code_buffer_insert_lines_at(GCodeBuffer *, GBufferLine **, size_t, size_t); -/* Retrouve l'indice associé à une ligne au sein d'un tampon. */ -static size_t g_code_buffer_find_index_by_line(const GCodeBuffer *, const GBufferLine *); + + +/* ------------------------- CONFORTS POUR LES COMMENTAIRES ------------------------- */ + + +/* Affiche un commentaire sur une ligne de tampon donnée. */ +static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *, GBufferLine *, const char *); + +/* Affiche un commentaire sur une ligne de tampon dédiée. */ +static bool _g_code_buffer_write_comment_area(GCodeBuffer *, GBufferLine *, const char *, bool); + +/* Retrouve la première ligne d'une zone de commentaire. */ +static size_t g_code_buffer_find_first_line_comment(const GCodeBuffer *, size_t); + +/* Retrouve la dernière ligne d'une zone de commentaire. */ +static size_t g_code_buffer_find_last_line_comment(const GCodeBuffer *, size_t); + +/* Supprime un commentaire existant. */ +static bool _g_code_buffer_delete_lines_comment(GCodeBuffer *, GBufferLine *); @@ -426,6 +444,591 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar) /* ---------------------------------------------------------------------------------- */ +/* CONFORTS POUR LES COMMENTAIRES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* line = ligne à l'intérieur d'un commentaire. * +* comment = nouveau commentaire à inscrire à la ligne donnée. * +* * +* Description : Affiche un commentaire sur une ligne de tampon donnée. * +* * +* Retour : Bilan de l'opération : ajout ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *buffer, GBufferLine *line, const char *comment) +{ + bool result; /* Bilan à retourner */ + const mrange_t *range; /* Emplace de ligne à utiliser */ + char *wcopy; /* Copie de travail */ + GBufferLine **extra; /* Lignes supplémentaires */ + size_t extra_count; /* Quantité de ces lignes */ + char *saveptr; /* Sauvegarde pour la sécurité */ + char *token; /* Fragment à insérer */ + size_t len; /* Taille dudit fragment */ + GBufferLine *new; /* Nouvelle ligne créée */ + size_t i; /* Boucle de parcours */ + + assert(!g_buffer_line_has_comment(line)); + + result = false; + + range = g_buffer_line_get_range(line); + + wcopy = strdup(comment); + + extra = NULL; + extra_count = 0; + + for (token = strtok_r(wcopy, COMMENT_LINE_SEP, &saveptr); + token != NULL; + token = strtok_r(NULL, COMMENT_LINE_SEP, &saveptr)) + { + len = strlen(token); + + if (!result) + g_buffer_line_insert_text(line, BLC_COMMENTS, token, len, RTT_COMMENT); + + else + { + new = g_code_buffer_prepare_new_line(buffer, range); + g_buffer_line_insert_text(new, BLC_COMMENTS, token, len, RTT_COMMENT); + + extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *)); + + extra[extra_count - 1] = new; + + } + + result = true; + + } + + free(wcopy); + + if (extra_count > 0) + { + result &= g_code_buffer_insert_lines(buffer, extra, extra_count, line, false); + + if (!result) + for (i = 0; i < extra_count; i++) + g_object_unref(G_OBJECT(extra[i])); + + free(extra); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* line = ligne à l'intérieur d'un commentaire. * +* comment = nouveau commentaire à inscrire à la ligne donnée. * +* * +* Description : Affiche un commentaire sur une ligne de tampon donnée. * +* * +* Retour : Bilan de l'opération : ajout ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_code_buffer_update_inlined_comment(GCodeBuffer *buffer, GBufferLine *line, const char *comment) +{ + bool result; /* Bilan à retourner */ + + if (g_buffer_line_has_comment(line)) + result = _g_code_buffer_delete_lines_comment(buffer, line); + else + result = true; + + if (result) + result = _g_code_buffer_write_inlined_comment(buffer, line, comment); + + /* TODO : emit() */ + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* line = ligne à l'intérieur d'un commentaire. * +* comment = nouveau commentaire à inscrire à la ligne donnée. * +* before = précise la position du commentaire. * +* * +* Description : Affiche un commentaire sur une ligne de tampon dédiée. * +* * +* Retour : Bilan de l'opération : ajout ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool _g_code_buffer_write_comment_area(GCodeBuffer *buffer, GBufferLine *line, const char *comment, bool before) +{ + bool result; /* Bilan à retourner */ + const mrange_t *range; /* Emplace de ligne à utiliser */ + char *wcopy; /* Copie de travail */ + GBufferLine **extra; /* Lignes supplémentaires */ + size_t extra_count; /* Quantité de ces lignes */ + char *saveptr; /* Sauvegarde pour la sécurité */ + char *token; /* Fragment à insérer */ + size_t len; /* Taille dudit fragment */ + GBufferLine *new; /* Nouvelle ligne créée */ + size_t i; /* Boucle de parcours */ + + assert(!g_buffer_line_has_comment(line)); + + result = false; + + range = g_buffer_line_get_range(line); + + wcopy = strdup(comment); + + extra = NULL; + extra_count = 0; + + for (token = strtok_r(wcopy, COMMENT_LINE_SEP, &saveptr); + token != NULL; + token = strtok_r(NULL, COMMENT_LINE_SEP, &saveptr)) + { + len = strlen(token); + + new = g_code_buffer_prepare_new_line(buffer, range); + g_buffer_line_start_merge_at(new, BLC_DISPLAY); + g_buffer_line_insert_text(new, BLC_DISPLAY, token, len, RTT_COMMENT); + + extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *)); + + extra[extra_count - 1] = new; + + result = true; + + } + + free(wcopy); + + if (extra_count > 0) + { + result &= g_code_buffer_insert_lines(buffer, extra, extra_count, line, before); + + if (!result) + for (i = 0; i < extra_count; i++) + g_object_unref(G_OBJECT(extra[i])); + + free(extra); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* line = ligne à l'intérieur d'un commentaire. * +* comment = nouveau commentaire à inscrire à la ligne donnée. * +* before = précise la position du commentaire. * +* * +* Description : Affiche un commentaire sur une ligne de tampon dédiée. * +* * +* Retour : Bilan de l'opération : ajout ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_code_buffer_update_comment_area(GCodeBuffer *buffer, GBufferLine *line, const char *comment, bool before) +{ + bool result; /* Bilan à retourner */ + + if (g_buffer_line_has_comment(line)) + result = _g_code_buffer_delete_lines_comment(buffer, line); + else + result = true; + + if (result) + result = _g_code_buffer_write_comment_area(buffer, line, comment, before); + + /* TODO : emit() */ + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* index = indice de ligne à l'intérieur d'un commentaire. * +* * +* Description : Retrouve la première ligne d'une zone de commentaire. * +* * +* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t g_code_buffer_find_first_line_comment(const GCodeBuffer *buffer, size_t index) +{ + size_t result; /* Indice trouvé à retourner */ + GBufferLine *prev; /* Ligne précédente */ + + assert(index < buffer->used); + + bool is_first_line_of_comment(const GBufferLine *ln, const GBufferLine *pv) + { + bool first; /* Statut à renvoyer */ + BufferLineColumn merge_col; /* Colonne de fusion #1 */ + BufferLineColumn prev_merge_col; /* Colonne de fusion #2 */ + + merge_col = g_buffer_line_get_merge_start(ln); + + /** + * La ligne consultée contient toujours un commentaire. + * + * Deux cas de figures sont possibles ici : + * + * - soit du texte est présent dans la colonne "commentaires". + * Si du texte est présent avant, alors il s'agit forcément de + * la première (et unique ?) ligne de commentaire. + * + * - soit la ligne effectue une fusion des colonnes depuis BLC_DISPLAY. + * Si la ligne qui précède fait de même, il s'agit alors d'une étiquette + * ou de l'amont du commentaire. + * + */ + + if (g_buffer_line_has_text(ln, BLC_COMMENTS, BLC_COUNT)) + { + first = g_buffer_line_has_text(ln, BLC_DISPLAY, BLC_COMMENTS); + + if (!first) + { + /* La ligne d'avant doit avoir un commentaire ! */ + first = !g_buffer_line_has_text(pv, BLC_COMMENTS, BLC_COUNT); + } + + } + + else + { + /** + * Le prologue "merge_col == BLC_FIRST" n'étant pas éditable, + * la seule fusion possible ici est la suivante. + */ + assert(merge_col == BLC_DISPLAY); + + /** + * La première ligne d'un tampon est toujours un prologue. + */ + assert(pv != NULL); + + prev_merge_col = g_buffer_line_get_merge_start(pv); + + first = (prev_merge_col != BLC_DISPLAY); + + if (!first) + first = (g_buffer_line_get_flags(pv) & BLF_IS_LABEL); + + } + + return first; + + } + + for (result = index; result > 0; result--) + { + prev = (result > 0 ? buffer->lines[result - 1] : NULL); + + if (is_first_line_of_comment(buffer->lines[result], prev)) + break; + + } + + if (result == 0) + { + if (!is_first_line_of_comment(buffer->lines[0], NULL)) + result = buffer->used; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* index = indice de ligne à l'intérieur d'un commentaire. * +* * +* Description : Retrouve la dernière ligne d'une zone de commentaire. * +* * +* Retour : Indice de l'adresse trouvée, ou le nombre de lignes sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t g_code_buffer_find_last_line_comment(const GCodeBuffer *buffer, size_t index) +{ + size_t result; /* Indice trouvé à retourner */ + GBufferLine *next; /* Ligne suivante */ + + assert(index < buffer->used); + + bool is_last_line_of_comment(const GBufferLine *ln, const GBufferLine *nx) + { + bool last; /* Statut à renvoyer */ + BufferLineColumn merge_col; /* Colonne de fusion #1 */ + BufferLineColumn next_merge_col; /* Colonne de fusion #2 */ + + merge_col = g_buffer_line_get_merge_start(ln); + + /** + * La ligne consultée contient toujours un commentaire. + * + * Deux cas de figures sont possibles ici : + * + * - soit du texte est présent dans la colonne "commentaires". + * Si la ligne suivante est similaire et si du texte est présent avant, + * alors il s'agit forcément de d'un nouveau commentaire. S'il n'y a + * aucun texte, il s'agit de la suite du commentaire. + * + * - soit la ligne effectue une fusion des colonnes depuis BLC_DISPLAY. + * Si la ligne qui suit fait de même, il s'agit alors d'une étiquette + * ou de l'aval du commentaire. + * + */ + + if (g_buffer_line_has_text(ln, BLC_COMMENTS, BLC_COUNT)) + { + last = !g_buffer_line_has_text(nx, BLC_COMMENTS, BLC_COUNT); + + if (!last) + last = g_buffer_line_has_text(nx, BLC_DISPLAY, BLC_COMMENTS); + + } + + else + { + /** + * Le prologue "merge_col == BLC_FIRST" n'étant pas éditable, + * la seule fusion possible ici est la suivante. + */ + assert(merge_col == BLC_DISPLAY); + + if (nx == NULL) + last = true; + + else + { + next_merge_col = g_buffer_line_get_merge_start(nx); + + last = (next_merge_col != BLC_DISPLAY); + + if (!last) + last = (g_buffer_line_get_flags(nx) & BLF_IS_LABEL); + + } + + } + + return last; + + } + + for (result = index; result < buffer->used; result++) + { + next = ((result + 1) < buffer->used ? buffer->lines[result + 1] : NULL); + + if (is_last_line_of_comment(buffer->lines[result], next)) + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à consulter. * +* line = ligne à l'intérieur d'un commentaire. * +* * +* Description : Récupère le contenu d'un commentaire existant. * +* * +* Retour : Commentaire retrouver à libérer ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *g_code_buffer_get_lines_comment(const GCodeBuffer *buffer, const GBufferLine *line) +{ + char *result; /* Contenu à retourner */ + size_t index; /* Indice de la ligne fournie */ + size_t start; /* Ligne de départ */ + size_t end; /* Ligne d'arrivée */ + BufferLineColumn merge_col; /* Colonne de fusion */ + size_t i; /* Boucle de parcours */ + char *extra; /* Commentaire supplémentaire */ + + /* Pas de prologue ici ! */ + assert(g_buffer_line_has_comment(line)); + + result = NULL; + + index = g_code_buffer_find_index_by_line(buffer, line); + + if (index == buffer->used) + goto gcbglc_exit; + + start = g_code_buffer_find_first_line_comment(buffer, index); + + if (start == buffer->used) + goto gcbglc_exit; + + end = g_code_buffer_find_last_line_comment(buffer, index); + + if (end == buffer->used) + goto gcbglc_exit; + + merge_col = g_buffer_line_get_merge_start(line); + + for (i = start; i <= end; i++) + { + if (merge_col == BLC_DISPLAY) + extra = g_buffer_line_get_text(buffer->lines[i], BLC_DISPLAY, BLC_COUNT, false); + + else + extra = g_buffer_line_get_text(buffer->lines[i], BLC_COMMENTS, BLC_COUNT, false); + + assert(extra != NULL); + + if (result == NULL) + result = extra; + + else + { + result = stradd(result, extra); + free(extra); + } + + } + + gcbglc_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à modifier. * +* line = ligne à l'intérieur d'un commentaire. * +* * +* Description : Supprime un commentaire existant. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool _g_code_buffer_delete_lines_comment(GCodeBuffer *buffer, GBufferLine *line) +{ + bool result; /* Bilan à retourner */ + size_t index; /* Indice de la ligne fournie */ + size_t start; /* Ligne de départ */ + size_t end; /* Ligne d'arrivée */ + BufferLineColumn merge_col; /* Colonne de fusion */ + + /* Pas de prologue ici ! */ + assert(g_buffer_line_has_comment(line)); + + result = false; + + index = g_code_buffer_find_index_by_line(buffer, line); + + if (index == buffer->used) + goto gcbdlc_exit; + + start = g_code_buffer_find_first_line_comment(buffer, index); + + if (start == buffer->used) + goto gcbdlc_exit; + + end = g_code_buffer_find_last_line_comment(buffer, index); + + if (end == buffer->used) + goto gcbdlc_exit; + + result = true; + + merge_col = g_buffer_line_get_merge_start(line); + + if (merge_col == BLC_DISPLAY) + g_code_buffer_delete_lines(buffer, start, end); + + else + { + g_buffer_line_delete_text(buffer->lines[start], BLC_COMMENTS, BLC_COUNT); + + if (end > start) + g_code_buffer_delete_lines(buffer, start + 1, end); + + } + + gcbdlc_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de lignes à modifier. * +* line = ligne à l'intérieur d'un commentaire. * +* * +* Description : Supprime un commentaire existant. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_code_buffer_delete_lines_comment(GCodeBuffer *buffer, GBufferLine *line) +{ + _g_code_buffer_delete_lines_comment(buffer, line); + + /* TODO : emit() */ + +} + + + +/* ---------------------------------------------------------------------------------- */ /* TAMPON POUR CODE DESASSEMBLE */ /* ---------------------------------------------------------------------------------- */ @@ -642,6 +1245,34 @@ static void g_code_buffer_update_line_max_widths(const GCodeBuffer *buffer, size /****************************************************************************** * * +* Paramètres : buffer = composant GLib à consulter. * +* range = emplacement où va se situer la ligne. * +* * +* Description : Initie une nouvelle ligne devant être insérée dans le tampon.* +* * +* Retour : Nouvelle ligne vierge à écrire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *buffer, const mrange_t *range) +{ + GBufferLine *result; /* Instance à retourner */ + size_t i; /* Boucle de parcours */ + + result = g_buffer_line_new(range, buffer->main_column); + + for (i = 0; i < buffer->indent; i++) + g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : line = ligne dont la définition vient d'évoluer. * * segment = éventuel segment qui vient d'évoluer ou NULL. * * buffer = tampon de lignes cohérentes à manipuler. * @@ -686,41 +1317,64 @@ static void on_line_flag_flip(GBufferLine *line, BufferLineFlags old, BufferLine /****************************************************************************** * * * Paramètres : buffer = composant GLib à mettre à jour. * -* range = emplacement où va se situer la ligne. * +* lines = liste de lignes à insérer. * +* count = taille de cette liste. * +* index = point d'insertion de la première ligne. * * * -* Description : Ajoute une nouvelle ligne à une position donnée. * +* Description : Ajoute de nouvelles lignes à une position donnée. * * * -* Retour : Nouvelle ligne vierge à écrire. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *buffer, size_t index, const mrange_t *range) +static void g_code_buffer_insert_lines_at(GCodeBuffer *buffer, GBufferLine **lines, size_t count, size_t index) { - GBufferLine *result; /* Instance à retourner */ size_t i; /* Boucle de parcours */ - if (buffer->used == buffer->count) + /* Elaboration d'un espace suffisant */ + + if ((buffer->used + count) > buffer->count) { - buffer->count += LINE_ALLOC_BULK; + if (count > LINE_ALLOC_BULK) + buffer->count += count; + else + buffer->count += LINE_ALLOC_BULK; + buffer->lines = (GBufferLine **)realloc(buffer->lines, buffer->count * sizeof(GBufferLine *)); + } - buffer->used++; - assert(index < buffer->used); + /* Insertion des lignes */ - result = g_buffer_line_new(range, buffer->main_column); - buffer->lines[index] = result; + if (index < buffer->used) + { + memmove(&buffer->lines[index + count], &buffer->lines[index], + (buffer->used - index) * sizeof(GBufferLine *)); + } - for (i = 0; i < buffer->indent; i++) - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW); + buffer->used += count; - g_signal_connect(result, "content-changed", G_CALLBACK(on_line_content_change), buffer); - g_signal_connect(result, "flip-flag", G_CALLBACK(on_line_flag_flip), buffer); + for (i = 0; i < count; i++) + { + assert((index + i) < buffer->used); - return result; + buffer->lines[index + i] = lines[i]; + + g_signal_connect(lines[i], "content-changed", G_CALLBACK(on_line_content_change), buffer); + g_signal_connect(lines[i], "flip-flag", G_CALLBACK(on_line_flag_flip), buffer); + + } + + /* Recueil initial des largeurs */ + + /** + * Comme des optimisations reposant sur des cas particuliers peuvent être + * réalisées ici, c'est à l'appelant de prendre cette charge de calculs à + * son compte ! + */ } @@ -728,21 +1382,78 @@ static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *buffer, size_t in /****************************************************************************** * * * Paramètres : buffer = composant GLib à mettre à jour. * -* range = emplacement où va se situer la ligne. * +* line = lign à insérer à la fin du tampon. * * * -* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. * +* Description : Ajoute une nouvelle ligne en fin de tampon. * * * -* Retour : Nouvelle ligne vierge à écrire. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *range) +void g_code_buffer_append_new_line(GCodeBuffer *buffer, GBufferLine *line) { - GBufferLine *result; /* Instance à retourner */ + GBufferLine *manager; /* Ligne de gestion de largeurs*/ - result = g_code_buffer_create_new_line(buffer, buffer->used, range); + g_code_buffer_insert_lines_at(buffer, (GBufferLine *[]) { line }, 1, buffer->used); + + /* Recueil initial des largeurs */ + + if (g_buffer_line_get_flags(line) & BLF_WIDTH_MANAGER) + manager = line; + + else + { + assert(buffer->used > 1); + manager = g_buffer_line_get_width_manager(buffer->lines[buffer->used - 2]); + } + + g_buffer_line_update_max_widths(line, manager); + +} + + +/****************************************************************************** +* * +* Paramètres : buffer = composant GLib à mettre à jour. * +* lines = liste de lignes à insérer. * +* count = taille de cette liste. * +* point = point d'insertion du bloc de ligne. * +* before = emplacement de l'insertion par rapport au point. * +* * +* Description : Ajoute de nouvelles lignes par rapport à une ligne donnée. * +* * +* Retour : Bilan : insertion réussie ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_code_buffer_insert_lines(GCodeBuffer *buffer, GBufferLine **lines, size_t count, const GBufferLine *point, bool before) +{ + bool result; /* Bilan à retourner */ + size_t index; /* Indice d'insertion final */ + + result = false; + + index = g_code_buffer_find_index_by_line(buffer, point); + + if (index == buffer->used) + goto gcbil_exit; + + if (!before) + index++; + + g_code_buffer_insert_lines_at(buffer, lines, count, index); + + + g_code_buffer_update_line_max_widths(buffer, index, index + count); + + + result = true; + + gcbil_exit: return result; @@ -751,6 +1462,45 @@ GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t * /****************************************************************************** * * +* Paramètres : buffer = composant GLib à mettre à jour. * +* start = première ligne devant être supprimée. * +* end = dernière ligne devant être supprimée. * +* * +* Description : Supprime une ou plusieurs lignes du tampon indiqué. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_buffer_delete_lines(GCodeBuffer *buffer, size_t start, size_t end) +{ + size_t i; /* Boucle de parcours */ + GBufferLine *line; /* Ligne en cours de traitement*/ + + assert(start < buffer->used); + assert(end < buffer->used); + + for (i = start; i <= end; i++) + { + line = buffer->lines[i]; + + g_signal_handlers_disconnect_by_func(line, G_CALLBACK(on_line_content_change), buffer); + g_signal_handlers_disconnect_by_func(line, G_CALLBACK(on_line_flag_flip), buffer); + + g_object_unref(G_OBJECT(line)); + + } + + memmove(&buffer->lines[start], &buffer->lines[end + 1], + (buffer->used - end - 1) * sizeof(GBufferLine *)); + +} + + +/****************************************************************************** +* * * Paramètres : buffer = composant GTK à mettre à jour. * * addr = adresse où retrouver la ligne recherchée. * * flags = propriétés à vérifier en tout ou partie. * @@ -844,7 +1594,7 @@ GBufferLine *g_code_buffer_find_line_by_index(const GCodeBuffer *buffer, size_t * * ******************************************************************************/ -static size_t g_code_buffer_find_index_by_line(const GCodeBuffer *buffer, const GBufferLine *line) +size_t g_code_buffer_find_index_by_line(const GCodeBuffer *buffer, const GBufferLine *line) { size_t result; /* Indice trouvé à retourner */ const mrange_t *range; /* Emplacement de la ligne */ @@ -1289,7 +2039,7 @@ static void g_buffer_view_compute_required_widths(GBufferView *view, const bool if (view->buffer->used > 0) { - g_code_buffer_update_line_max_widths(view->buffer, first, last); + //g_code_buffer_update_line_max_widths(view->buffer, first, last); for (i = first; i <= last; i++) g_buffer_line_apply_max_widths(lines[i], view->max_widths, &view->merged_width); |