summaryrefslogtreecommitdiff
path: root/src/glibext/gcodebuffer.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-01-21 20:51:27 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-01-21 21:23:58 (GMT)
commitdd33acbff36c0a3ae4618ac5021e74448cad5ce5 (patch)
tree834351b836760fc54533e2f39c4b8202e695c0e3 /src/glibext/gcodebuffer.c
parente3ee1abf12d7868f5eaf759e04a4b4911fcdfa91 (diff)
Defined some raw primitives to write or delete comments.
Diffstat (limited to 'src/glibext/gcodebuffer.c')
-rw-r--r--src/glibext/gcodebuffer.c806
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);