From: Olaf Wintermann Date: Tue, 3 Feb 2026 18:32:44 +0000 (+0100) Subject: implement text replace X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=HEAD;p=note.git implement text replace --- diff --git a/application/note.c b/application/note.c index acf5c83..dfaec7c 100644 --- a/application/note.c +++ b/application/note.c @@ -33,6 +33,8 @@ #include "notebook.h" #include "attachment.h" +#include "../utils/strreplace.h" + #include static TextNoteParagraphStyles paragraph_styles[] = { @@ -422,7 +424,26 @@ static int get_search_start_pos(NoteModel *note, bool backwards) { return pos; } -static void note_search(NoteModel *note, bool backwards) { +typedef struct { + cxstring text; + regmatch_t *match; + size_t nmatch; +} TplStringBuildData; + +static cxmutstr get_group(const CxAllocator *a, StringTemplateSegment *seg, void *userdata, bool *free_str) { + TplStringBuildData *data = userdata; + if(seg->num >= data->nmatch) { + return CX_NULLSTR; + } + regmatch_t match = data->match[seg->num]; + if(match.rm_so < 0 || match.rm_eo < 0) { + return CX_NULLSTR; + } + cxstring s = cx_strsubsl(data->text, match.rm_so, match.rm_eo-match.rm_so); + return cx_mutstrn((char*)s.ptr, s.length); +} + +static void note_search(NoteModel *note, bool backwards, bool replace) { cxstring searchstr = cx_str(ui_get(note->search)); if(searchstr.length == 0) { return; @@ -446,10 +467,24 @@ static void note_search(NoteModel *note, bool backwards) { } int begin, end; - if(text_search(text, searchstr, pos, backwards, cs, enable_regex ? ®ex : NULL, &begin, &end)) { - note->text->setposition(note->text, end); - note->text->setselection(note->text, begin, end); - note->text->showposition(note->text, begin); + regmatch_t match[32]; + if(text_search_match(text, searchstr, pos, backwards, cs, enable_regex ? ®ex : NULL, &begin, &end, match, 32)) { + if(!replace) { + note->text->setposition(note->text, end); + note->text->setselection(note->text, begin, end); + note->text->showposition(note->text, begin); + } else { + cxstring tpl_str = cx_str(ui_get(note->replace)); + StringTemplate *tpl = string_template_compile(cxDefaultAllocator, tpl_str); + TplStringBuildData data; + data.match = match; + data.nmatch = 32; + data.text = text; + cxmutstr replacement = string_template_build_string(tpl, cxDefaultAllocator, get_group, &data); + note->text->replace(note->text, begin, end, replacement.ptr); + free(replacement.ptr); + string_template_free(tpl); + } } if(enable_regex) { @@ -458,13 +493,13 @@ static void note_search(NoteModel *note, bool backwards) { } void note_search_next(NoteModel *note) { - note_search(note, FALSE); + note_search(note, FALSE, FALSE); } void note_search_prev(NoteModel *note) { - note_search(note, TRUE); + note_search(note, TRUE, FALSE); } void note_replace(NoteModel *note) { - + note_search(note, FALSE, TRUE); } diff --git a/ui/cocoa/text.h b/ui/cocoa/text.h index 23bc438..415717c 100644 --- a/ui/cocoa/text.h +++ b/ui/cocoa/text.h @@ -37,7 +37,7 @@ void ui_textarea_restore(UiText *text); void ui_textarea_set(UiText *text, const char *str); char* ui_textarea_get(UiText *text); char* ui_textarea_getsubstr(UiText *text, int begin, int end); -void ui_textarea_insert(UiText *text, int pos, char *str); +void ui_textarea_insert(UiText *text, int pos, const char *str); void ui_textarea_setposition(UiText *text, int pos); int ui_textarea_position(UiText *text); void ui_textarea_setselection(UiText *text, int begin, int end); diff --git a/ui/cocoa/text.m b/ui/cocoa/text.m index 324d6e7..679968f 100644 --- a/ui/cocoa/text.m +++ b/ui/cocoa/text.m @@ -120,7 +120,7 @@ char* ui_textarea_getsubstr(UiText *text, int begin, int end) { return strdup(sub.UTF8String); } -void ui_textarea_insert(UiText *text, int pos, char *str) { +void ui_textarea_insert(UiText *text, int pos, const char *str) { NSTextView *textview = (__bridge NSTextView*)text->obj; NSString *s = [[NSString alloc] initWithUTF8String:str]; NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithString:s]; diff --git a/ui/common/types.c b/ui/common/types.c index 38e6b6c..e0ecf51 100644 --- a/ui/common/types.c +++ b/ui/common/types.c @@ -676,6 +676,7 @@ void uic_text_copy(UiText *from, UiText *to) { to->set = from->set; to->getsubstr = from->getsubstr; to->insert = from->insert; + to->replace = from->replace; to->setposition = from->setposition; to->position = from->position; to->showposition = from->showposition; @@ -768,9 +769,11 @@ void uic_text_unbind(UiText *t) { t->get = NULL; t->getsubstr = NULL; t->insert = NULL; + t->replace = NULL; t->setposition = NULL; t->position = NULL; t->selection = NULL; + t->setselection = NULL; t->length = NULL; t->remove = NULL; t->obj = NULL; diff --git a/ui/gtk/text.c b/ui/gtk/text.c index fd355ee..e9dc703 100644 --- a/ui/gtk/text.c +++ b/ui/gtk/text.c @@ -186,6 +186,7 @@ UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) { value->set = ui_textarea_set; value->getsubstr = ui_textarea_getsubstr; value->insert = ui_textarea_insert; + value->replace = ui_textarea_replace; value->setposition = ui_textarea_setposition; value->position = ui_textarea_position; value->showposition = ui_textarea_showposition; @@ -287,7 +288,7 @@ char* ui_textarea_getsubstr(UiText *text, int begin, int end) { return str; } -void ui_textarea_insert(UiText *text, int pos, char *str) { +void ui_textarea_insert(UiText *text, int pos, const char *str) { GtkTextIter offset; gtk_text_buffer_get_iter_at_offset(text->data1, &offset, pos); gtk_text_buffer_insert(text->data1, &offset, str, -1); @@ -298,6 +299,20 @@ void ui_textarea_insert(UiText *text, int pos, char *str) { text->value.free = NULL; } +void ui_textarea_replace(UiText *text, int begin, int end, const char *replacement) { + GtkTextBuffer *buffer = text->data1; + GtkTextIter begin_offset; + GtkTextIter end_offset; + gtk_text_buffer_get_iter_at_offset(buffer, &begin_offset, begin); + gtk_text_buffer_get_iter_at_offset(buffer, &end_offset, end); + gtk_text_buffer_begin_user_action(buffer); + gtk_text_buffer_delete(buffer, &begin_offset, &end_offset); + if(replacement) { + gtk_text_buffer_insert(buffer, &begin_offset, replacement, -1); + } + gtk_text_buffer_end_user_action(buffer); +} + void ui_textarea_setposition(UiText *text, int pos) { GtkTextIter iter; gtk_text_buffer_get_iter_at_offset(text->data1, &iter, pos); diff --git a/ui/gtk/text.h b/ui/gtk/text.h index a976cbc..4d306aa 100644 --- a/ui/gtk/text.h +++ b/ui/gtk/text.h @@ -117,7 +117,8 @@ void ui_textarea_text_destroy(UiText *text); char* ui_textarea_get(UiText *text); void ui_textarea_set(UiText *text, const char *str); char* ui_textarea_getsubstr(UiText *text, int begin, int end); -void ui_textarea_insert(UiText *text, int pos, char *str); +void ui_textarea_insert(UiText *text, int pos, const char *str); +void ui_textarea_replace(UiText *text, int begin, int end, const char *replacement); void ui_textarea_setposition(UiText *text, int pos); int ui_textarea_position(UiText *text); void ui_textarea_showposition(UiText *text, int pos); diff --git a/ui/motif/text.c b/ui/motif/text.c index 877659f..f0dd46c 100644 --- a/ui/motif/text.c +++ b/ui/motif/text.c @@ -150,9 +150,9 @@ char* ui_textarea_getsubstr(UiText *text, int begin, int end) { return str; } -void ui_textarea_insert(UiText *text, int pos, char *str) { +void ui_textarea_insert(UiText *text, int pos, const char *str) { text->value.ptr = NULL; - XmTextInsert(text->obj, pos, str); + XmTextInsert(text->obj, pos, (char*)str); if(text->value.ptr) { text->value.free(text->value.ptr); } diff --git a/ui/motif/text.h b/ui/motif/text.h index 9f2932e..3c59627 100644 --- a/ui/motif/text.h +++ b/ui/motif/text.h @@ -70,7 +70,7 @@ void ui_textarea_text_destroy(UiText *text); char* ui_textarea_get(UiText *text); void ui_textarea_set(UiText *text, const char *str); char* ui_textarea_getsubstr(UiText *text, int begin, int end); -void ui_textarea_insert(UiText *text, int pos, char *str); +void ui_textarea_insert(UiText *text, int pos, const char *str); void ui_textarea_setposition(UiText *text, int pos); int ui_textarea_position(UiText *text); void ui_textarea_selection(UiText *text, int *begin, int *end); diff --git a/ui/qt/text.cpp b/ui/qt/text.cpp index 9582478..2aeab47 100644 --- a/ui/qt/text.cpp +++ b/ui/qt/text.cpp @@ -154,7 +154,7 @@ char* ui_textarea_getsubstr(UiText *text, int begin, int end) { return cstr ? strdup(cstr) : NULL; } -void ui_textarea_insert(UiText *text, int pos, char *str) { +void ui_textarea_insert(UiText *text, int pos, const char *str) { QTextDocument *doc = (QTextDocument*)text->data1; QTextCursor cursor(doc); cursor.setPosition(pos); diff --git a/ui/qt/text.h b/ui/qt/text.h index fcfe612..5ecee2a 100644 --- a/ui/qt/text.h +++ b/ui/qt/text.h @@ -43,7 +43,7 @@ void ui_textarea_text_destroy(UiText *text); char* ui_textarea_get(UiText *text); void ui_textarea_set(UiText *text, const char *str); char* ui_textarea_getsubstr(UiText *text, int begin, int end); -void ui_textarea_insert(UiText *text, int pos, char *str); +void ui_textarea_insert(UiText *text, int pos, const char *str); void ui_textarea_setposition(UiText *text, int pos); int ui_textarea_position(UiText *text); void ui_textarea_setselection(UiText *text, int begin, int end); diff --git a/ui/ui/toolkit.h b/ui/ui/toolkit.h index 9fbc658..8833f90 100644 --- a/ui/ui/toolkit.h +++ b/ui/ui/toolkit.h @@ -392,7 +392,8 @@ struct UiText { void (*set)(UiText*, const char*); char* (*get)(UiText*); char* (*getsubstr)(UiText*, int, int); /* text, begin, end */ - void (*insert)(UiText*, int, char*); + void (*insert)(UiText*, int, const char*); + void (*replace)(UiText*, int, int, const char*); void (*setposition)(UiText*,int); int (*position)(UiText*); void (*showposition)(UiText*, int);