From 2fdb6559282049a006dc589fdba6a6fd248f1173 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Wed, 18 Feb 2026 18:31:24 +0100 Subject: [PATCH] add function for reordering text lists --- application/gtk-text.c | 143 +++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 34 deletions(-) diff --git a/application/gtk-text.c b/application/gtk-text.c index a2450d2..1ba99f1 100644 --- a/application/gtk-text.c +++ b/application/gtk-text.c @@ -292,16 +292,8 @@ static void em_remove_anchor(BufferEmbeddedObjects *em, GtkTextChildAnchor *anch } } -static void editor_delete_range_cb( - GtkTextBuffer *buffer, - const GtkTextIter *start, - const GtkTextIter *end, - NoteEditor *editor) -{ - -} -static int get_prev_list(GtkTextBuffer *buffer, const GtkTextIter *iter, int *depth, int *style, int *num, int *remove_offset) { +static int iter_is_list(GtkTextBuffer *buffer, const GtkTextIter *iter, int *depth, int *style, int *num, int *offset, int *isempty) { int list_depth = 0; int list_style = 0; int list_num = 0; @@ -337,20 +329,82 @@ static int get_prev_list(GtkTextBuffer *buffer, const GtkTextIter *iter, int *de } if(list_depth > 0) { - if(chars_per_line == 1) { - list_depth = 0; - *remove_offset = off + 1; - } else { - *depth = list_depth; - *style = list_style; - *num = list_num; - *remove_offset = -1; - return 1; - } + *isempty = chars_per_line == 1; + *depth = list_depth; + *style = list_style; + *num = list_num; + *offset = off + 1; + return 1; } return 0; } +static void reorder_list(GtkTextBuffer *buffer, const GtkTextIter *begin) { + GtkTextIter i = *begin; + + GtkTextChildAnchor *anchor = NULL; + GtkTextChildAnchor *prevAnchor = NULL; + int line_is_list = 0; + int num = 1; + + while(gtk_text_iter_forward_char(&i)) { + if(gtk_text_iter_get_char(&i) == '\n') { + if(!line_is_list) { + break; + } + line_is_list = 0; + } + + anchor = gtk_text_iter_get_child_anchor(&i); + if(anchor && anchor != prevAnchor) { + EmbeddedWidget *em = g_object_get_data(G_OBJECT(anchor), "em"); + if(em && em->type == EMBEDDED_WIDGET_LIST) { + line_is_list = 1; + if(em->intdata1 == 0) { + em->intdata2 = num++; + ui_widget_redraw(em->widget); + } + } + } + prevAnchor = anchor; + } +} + +static int get_list_begin(GtkTextBuffer *buffer, const GtkTextIter *iter, GtkTextIter *begin) { + GtkTextIter i = *iter; + GtkTextIter prev = i; + int line_is_list = 0; + int is_list = 0; + + GtkTextChildAnchor *anchor = NULL; + GtkTextChildAnchor *prevAnchor = NULL; + + while(gtk_text_iter_backward_char(&i)) { + if(gtk_text_iter_get_char(&i) == '\n') { + if(!line_is_list) { + *begin = prev; + return is_list; + } + line_is_list = 0; + } + + anchor = gtk_text_iter_get_child_anchor(&i); + if(anchor && anchor != prevAnchor) { + EmbeddedWidget *em = g_object_get_data(G_OBJECT(anchor), "em"); + if(em && em->type == EMBEDDED_WIDGET_LIST) { + line_is_list = 1; + is_list = 1; + } + } + prevAnchor = anchor; + + prev = i; + } + *begin = prev; + + return is_list; +} + static void edit_insert_text_cb( GtkTextBuffer *buffer, const GtkTextIter *location, @@ -376,10 +430,11 @@ static void edit_insert_text_cb( int list_style = 0; int list_num = 0; int remove_list_off = -1; + int isempty = 0; if(nlines > 1) { // Inserted text contains at least one linebreak // Check if the current line contains a list - (void)get_prev_list(buffer, &begin, &list_depth, &list_style, &list_num, &remove_list_off); + (void)iter_is_list(buffer, &begin, &list_depth, &list_style, &list_num, &remove_list_off, &isempty); } GtkTextIter prev = begin; @@ -414,26 +469,46 @@ static void edit_insert_text_cb( } if(list_depth > 0) { - // Insert list elements for all inserted lines - // The first line is skipped, because the text will be part of the current list line - const char *style_name = list_style == 1 ? EDITOR_STYLE_LIST0 : EDITOR_STYLE_ORDLIST0; - for(int i=nlines-1;i>0;i--) { - intptr_t line_off = (intptr_t)(lines[i].ptr - text); + if(!isempty) { + // Insert list elements for all inserted lines + // The first line is skipped, because the text will be part of the current list line + const char *style_name = list_style == 1 ? EDITOR_STYLE_LIST0 : EDITOR_STYLE_ORDLIST0; + for(int i=nlines-1;i>0;i--) { + intptr_t line_off = (intptr_t)(lines[i].ptr - text); + GtkTextIter iter; + gtk_text_buffer_get_iter_at_offset(buffer, &iter, insert_offset + line_off); + editor_insert_list_element(editor, &iter, style_name, list_num+i); + } + } else { GtkTextIter iter; - gtk_text_buffer_get_iter_at_offset(buffer, &iter, insert_offset + line_off); - editor_insert_list_element(editor, &iter, style_name, list_num+i); + gtk_text_buffer_get_iter_at_offset(buffer, &iter, remove_list_off-1); + GtkTextIter iter2 = iter; + gtk_text_iter_forward_char(&iter2); + gtk_text_buffer_delete(buffer, &iter, &iter2); + } + + GtkTextIter list_begin; + int islist = get_list_begin(buffer, &begin, &list_begin); + if(islist) { + reorder_list(buffer, &list_begin); } } - - if(remove_list_off > 0) { - GtkTextIter iter; - gtk_text_buffer_get_iter_at_offset(buffer, &iter, remove_list_off-1); - GtkTextIter iter2 = iter; - gtk_text_iter_forward_char(&iter2); - gtk_text_buffer_delete(buffer, &iter, &iter2); +} + +static void editor_delete_range_cb( + GtkTextBuffer *buffer, + const GtkTextIter *start, + const GtkTextIter *end, + NoteEditor *editor) +{ + GtkTextIter list_begin; + int islist = get_list_begin(buffer, start, &list_begin); + if(islist) { + reorder_list(buffer, &list_begin); } } + static gboolean path_is_image_file(cxstring path) { if(path.length == 0) { return FALSE; -- 2.47.3