Forum > GTK

[SOLVED]Question about GTK2 text coloring

(1/2) > >>

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

Go to full version