Forum > GTK
[SOLVED]Question about GTK2 text coloring
tomitomy:
Hello everyone, I'm writing syntax highlighting in GTK2 and I'm having a problem, when I copy the colored text from one node to another, the text is misaligned and the console outputs:
--- Quote ---Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
--- End quote ---
I use the following code to implement text coloring:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure THighLight.NewTag( Name : String; FGColor : String = '000000'; Bolb : Boolean = False; Italic : Boolean = False; Underline : Boolean = False); var GdkFGColor : TGdkColor; BlobFlag : LongWord; ItalicFlag : LongWord; UnderlineFlag : LongWord;begin gdk_color_parse(PChar('#' + FGColor), @GdkFGColor); if Bolb then BlobFlag := PANGO_WEIGHT_BOLD else BlobFlag := PANGO_WEIGHT_NORMAL; if Italic then ItalicFlag := PANGO_STYLE_ITALIC else ItalicFlag := PANGO_STYLE_NORMAL; if Underline then UnderlineFlag := PANGO_UNDERLINE_SINGLE else UnderlineFlag := PANGO_UNDERLINE_NONE; gtk_text_buffer_create_tag(GBuffer, PGChar(Name), 'foreground-gdk', [ @GdkFGColor, 'weight' , BlobFlag, 'style' , ItalicFlag, 'underline' , UnderlineFlag ]);end; procedure THighLight.SetTag(SelStart, SelLenth: Integer; Style: String);begin gtk_text_buffer_get_iter_at_offset(GBuffer, @GStartIter, SelStart); gtk_text_buffer_get_iter_at_offset(GBuffer, @GEndIter , SelStart + SelLenth); gtk_text_buffer_apply_tag_by_name (GBuffer, PGChar(Style), @GStartIter, @GEndIter);end; procedure THighLight.DelTag(SelStart, SelLenth: Integer; Style: String);begin gtk_text_buffer_get_iter_at_offset(GBuffer, @GStartIter, SelStart); gtk_text_buffer_get_iter_at_offset(GBuffer, @GEndIter , SelStart + SelLenth); gtk_text_buffer_remove_tag_by_name(GBuffer, PGChar(Style), @GStartIter, @GEndIter);end; procedure THighLight.ClearTag();begin gtk_text_buffer_get_start_iter (GBuffer, @GStartIter); gtk_text_buffer_get_end_iter (GBuffer, @GEndIter); gtk_text_buffer_remove_all_tags(GBuffer, @GStartIter, @GEndIter);end;
I don't know how to fix this problem. Can someone help me?
I upload the source code to the attachment.
zeljko:
Have you tried to get gbuffer as local variable inside each of your functions where you need GBuffer ? AGBuffer := gtk_text_view_get_buffer(GView); ?
tomitomy:
--- Quote from: zeljko on January 26, 2023, 06:32:35 pm ---Have you tried to get gbuffer as local variable inside each of your functions where you need GBuffer ? AGBuffer := gtk_text_view_get_buffer(GView); ?
--- End quote ---
Yes, I tried, the problem persists, I tested with the short code below, when I cut all the text in Memo1 and then pasted it in place, the text was misplaced.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Gtk2, GLib2, Gdk2, Gtk2Proc; type { TForm1 } TForm1 = class(TForm) Memo1: TMemo; procedure FormCreate(Sender: TObject); private GView : PGtkTextView; //GBuffer : PGtkTextBuffer; GStartIter : TGtkTextIter; GEndIter : TGtkTextIter; procedure NewTag(AName, AColor: String); procedure SetTag(SelStart, SelLenth: Integer; Style: String); end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject);begin Memo1.Text := 'Hello World!'; GView := GTK_TEXT_VIEW(GetWidgetInfo({%H-}PGtkWidget(Memo1.Handle))^.CoreWidget); //GBuffer := gtk_text_view_get_buffer(GView); NewTag('test', 'FF0000'); SetTag(6, 5, 'test');end; procedure TForm1.NewTag(AName, AColor: String);var GdkColor: TGdkColor; GBuffer : PGtkTextBuffer;begin GBuffer := gtk_text_view_get_buffer(GView); gdk_color_parse (PChar('#' + AColor), @GdkColor); gtk_text_buffer_create_tag(GBuffer, PGChar(AName), 'foreground-gdk', [@GdkColor]);end; procedure TForm1.SetTag(SelStart, SelLenth: Integer; Style: String);var GBuffer: PGtkTextBuffer;begin GBuffer := gtk_text_view_get_buffer(GView); gtk_text_buffer_get_iter_at_offset(GBuffer, @GStartIter, SelStart); gtk_text_buffer_get_iter_at_offset(GBuffer, @GEndIter , SelStart + SelLenth); gtk_text_buffer_apply_tag_by_name (GBuffer, PGChar(Style), @GStartIter, @GEndIter);end; end.
tomitomy:
Is this a bug or is there a problem with my code? When I create the window directly using the GTK function, without LCL, it works fine:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; uses Classes, SysUtils, glib2, gtk2, gdk2, pango; var Window : PGtkWidget; View : PGtkWidget; Buffer : PGtkTextBuffer; StartIter : TGtkTextIter; EndIter : TGtkTextIter; procedure NewTag(Tag: String; Color: String= '000000'); var GdkColor : TGdkColor; begin gdk_color_parse(PChar('#' + Color), @GdkColor); gtk_text_buffer_create_tag(Buffer, PGChar(Tag), 'foreground-gdk', [@GdkColor]); end; procedure SetTag(SelStart, SelLenth: Integer; Tag: String); begin gtk_text_buffer_get_iter_at_offset(Buffer, @StartIter, SelStart); gtk_text_buffer_get_iter_at_offset(Buffer, @EndIter , SelStart + SelLenth); gtk_text_buffer_apply_tag_by_name (Buffer, PGChar(Tag), @StartIter, @EndIter); end; begin gtk_init(@argc, @argv); Window := gtk_window_new (GTK_WINDOW_TOPLEVEL); View := gtk_text_view_new (); Buffer := gtk_text_view_get_buffer (GTK_TEXT_VIEW(View)); gtk_window_set_position (GTK_WINDOW(Window) , GTK_WIN_POS_CENTER); gtk_window_set_default_size (GTK_WINDOW(Window) , 600, 400); gtk_container_add (PGtkContainer(Window) , View); gtk_text_buffer_get_iter_at_offset(Buffer, @StartIter, 0); gtk_text_buffer_insert (Buffer, @StartIter, 'Hello world!'#10, -1); NewTag('test', 'FF0000'); SetTag(6, 5, 'test'); g_signal_connect_swapped(G_OBJECT(Window), 'destroy', G_CALLBACK(@gtk_main_quit), G_OBJECT(Window)); gtk_widget_show_all (Window); gtk_main();end.[code]
tomitomy:
I use "ClipBoard.AsText" to remove the format to avoid this problem.
Navigation
[0] Message Index
[#] Next page