Recent

Author Topic: [SOLVED]Question about GTK2 text coloring  (Read 2605 times)

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
[SOLVED]Question about GTK2 text coloring
« on: January 26, 2023, 05:06:44 pm »
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

I use the following code to implement text coloring:

Code: Pascal  [Select][+][-]
  1. procedure THighLight.NewTag(
  2.   Name       : String;
  3.   FGColor    : String  = '000000';
  4.   Bolb       : Boolean = False;
  5.   Italic     : Boolean = False;
  6.   Underline  : Boolean = False
  7. );
  8.  
  9. var
  10.   GdkFGColor    : TGdkColor;
  11.   BlobFlag      : LongWord;
  12.   ItalicFlag    : LongWord;
  13.   UnderlineFlag : LongWord;
  14. begin
  15.   gdk_color_parse(PChar('#' + FGColor), @GdkFGColor);
  16.  
  17.   if Bolb then
  18.     BlobFlag := PANGO_WEIGHT_BOLD
  19.   else
  20.     BlobFlag := PANGO_WEIGHT_NORMAL;
  21.  
  22.   if Italic then
  23.     ItalicFlag := PANGO_STYLE_ITALIC
  24.   else
  25.     ItalicFlag := PANGO_STYLE_NORMAL;
  26.  
  27.   if Underline then
  28.     UnderlineFlag := PANGO_UNDERLINE_SINGLE
  29.   else
  30.     UnderlineFlag := PANGO_UNDERLINE_NONE;
  31.  
  32.   gtk_text_buffer_create_tag(GBuffer, PGChar(Name), 'foreground-gdk', [
  33.     @GdkFGColor,
  34.     'weight'        , BlobFlag,
  35.     'style'         , ItalicFlag,
  36.     'underline'     , UnderlineFlag
  37.   ]);
  38. end;
  39.  
  40. procedure THighLight.SetTag(SelStart, SelLenth: Integer; Style: String);
  41. begin
  42.   gtk_text_buffer_get_iter_at_offset(GBuffer, @GStartIter, SelStart);
  43.   gtk_text_buffer_get_iter_at_offset(GBuffer, @GEndIter  , SelStart + SelLenth);
  44.   gtk_text_buffer_apply_tag_by_name (GBuffer, PGChar(Style), @GStartIter, @GEndIter);
  45. end;
  46.  
  47. procedure THighLight.DelTag(SelStart, SelLenth: Integer; Style: String);
  48. begin
  49.   gtk_text_buffer_get_iter_at_offset(GBuffer, @GStartIter, SelStart);
  50.   gtk_text_buffer_get_iter_at_offset(GBuffer, @GEndIter  , SelStart + SelLenth);
  51.   gtk_text_buffer_remove_tag_by_name(GBuffer, PGChar(Style), @GStartIter, @GEndIter);
  52. end;
  53.  
  54. procedure THighLight.ClearTag();
  55. begin
  56.   gtk_text_buffer_get_start_iter (GBuffer, @GStartIter);
  57.   gtk_text_buffer_get_end_iter   (GBuffer, @GEndIter);
  58.   gtk_text_buffer_remove_all_tags(GBuffer, @GStartIter, @GEndIter);
  59. end;

I don't know how to fix this problem. Can someone help me?

I upload the source code to the attachment.
« Last Edit: March 05, 2023, 03:00:27 am by tomitomy »

zeljko

  • Hero Member
  • *****
  • Posts: 1624
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Question about GTK2 text coloring
« Reply #1 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); ?

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: Question about GTK2 text coloring
« Reply #2 on: January 27, 2023, 02:25:17 am »
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); ?

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  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   Gtk2, GLib2, Gdk2, Gtk2Proc;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.  
  17.     Memo1: TMemo;
  18.     procedure FormCreate(Sender: TObject);
  19.  
  20.   private
  21.  
  22.     GView      : PGtkTextView;
  23.     //GBuffer  : PGtkTextBuffer;
  24.     GStartIter : TGtkTextIter;
  25.     GEndIter   : TGtkTextIter;
  26.  
  27.     procedure NewTag(AName, AColor: String);
  28.     procedure SetTag(SelStart, SelLenth: Integer; Style: String);
  29.  
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TForm1 }
  40.  
  41. procedure TForm1.FormCreate(Sender: TObject);
  42. begin
  43.   Memo1.Text := 'Hello World!';
  44.  
  45.   GView := GTK_TEXT_VIEW(GetWidgetInfo({%H-}PGtkWidget(Memo1.Handle))^.CoreWidget);
  46.   //GBuffer := gtk_text_view_get_buffer(GView);
  47.   NewTag('test', 'FF0000');
  48.   SetTag(6, 5, 'test');
  49. end;
  50.  
  51. procedure TForm1.NewTag(AName, AColor: String);
  52. var
  53.   GdkColor: TGdkColor;
  54.   GBuffer : PGtkTextBuffer;
  55. begin
  56.   GBuffer := gtk_text_view_get_buffer(GView);
  57.  
  58.   gdk_color_parse           (PChar('#' + AColor), @GdkColor);
  59.   gtk_text_buffer_create_tag(GBuffer, PGChar(AName), 'foreground-gdk', [@GdkColor]);
  60. end;
  61.  
  62. procedure TForm1.SetTag(SelStart, SelLenth: Integer; Style: String);
  63. var
  64.   GBuffer: PGtkTextBuffer;
  65. begin
  66.   GBuffer := gtk_text_view_get_buffer(GView);
  67.  
  68.   gtk_text_buffer_get_iter_at_offset(GBuffer, @GStartIter, SelStart);
  69.   gtk_text_buffer_get_iter_at_offset(GBuffer, @GEndIter  , SelStart + SelLenth);
  70.   gtk_text_buffer_apply_tag_by_name (GBuffer, PGChar(Style), @GStartIter, @GEndIter);
  71. end;
  72.  
  73. end.
« Last Edit: January 27, 2023, 02:42:00 am by tomitomy »

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: Question about GTK2 text coloring
« Reply #3 on: January 28, 2023, 02:26:14 am »
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  [Select][+][-]
  1. program Project1;
  2.  
  3. uses
  4.   Classes, SysUtils, glib2, gtk2, gdk2, pango;
  5.  
  6. var
  7.   Window     : PGtkWidget;
  8.   View       : PGtkWidget;
  9.   Buffer     : PGtkTextBuffer;
  10.   StartIter  : TGtkTextIter;
  11.   EndIter    : TGtkTextIter;
  12.  
  13.   procedure NewTag(Tag: String; Color: String= '000000');
  14.   var
  15.     GdkColor      : TGdkColor;
  16.   begin
  17.     gdk_color_parse(PChar('#' + Color), @GdkColor);
  18.     gtk_text_buffer_create_tag(Buffer, PGChar(Tag), 'foreground-gdk', [@GdkColor]);
  19.   end;
  20.  
  21.   procedure SetTag(SelStart, SelLenth: Integer; Tag: String);
  22.   begin
  23.     gtk_text_buffer_get_iter_at_offset(Buffer, @StartIter, SelStart);
  24.     gtk_text_buffer_get_iter_at_offset(Buffer, @EndIter  , SelStart + SelLenth);
  25.     gtk_text_buffer_apply_tag_by_name (Buffer, PGChar(Tag), @StartIter, @EndIter);
  26.   end;
  27.  
  28. begin
  29.   gtk_init(@argc, @argv);
  30.  
  31.   Window := gtk_window_new           (GTK_WINDOW_TOPLEVEL);
  32.   View   := gtk_text_view_new        ();
  33.   Buffer := gtk_text_view_get_buffer (GTK_TEXT_VIEW(View));
  34.  
  35.   gtk_window_set_position        (GTK_WINDOW(Window)    , GTK_WIN_POS_CENTER);
  36.   gtk_window_set_default_size    (GTK_WINDOW(Window)    , 600, 400);
  37.   gtk_container_add              (PGtkContainer(Window) , View);
  38.  
  39.   gtk_text_buffer_get_iter_at_offset(Buffer, @StartIter, 0);
  40.   gtk_text_buffer_insert            (Buffer, @StartIter, 'Hello world!'#10, -1);
  41.  
  42.   NewTag('test', 'FF0000');
  43.   SetTag(6, 5, 'test');
  44.  
  45.   g_signal_connect_swapped(G_OBJECT(Window), 'destroy', G_CALLBACK(@gtk_main_quit), G_OBJECT(Window));
  46.   gtk_widget_show_all     (Window);
  47.   gtk_main();
  48. end.[code]

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: Question about GTK2 text coloring
« Reply #4 on: March 05, 2023, 02:58:52 am »
I use "ClipBoard.AsText" to remove the format to avoid this problem.

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: [SOLVED]Question about GTK2 text coloring
« Reply #5 on: May 07, 2023, 06:03:58 am »
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:

......

I upload the source code to the attachment.

The attachment I uploaded earlier had a serious bug that caused data loss, I re-uploaded it here, the newly uploaded attachment fixed this bug(uTreeDB.pas), I tested for several months and did not encounter a new bug.

I didn't find the button to edit the old post, so I can't delete the attachment in the old post, if anyone is interested in this attachment, please re-download the new attachment here.


This project is an upgraded version of TomiNote v1.1 which I released a few years ago, and basically works (Linux only), supports syntax coloring and search result highlighting. Some features have not yet been implemented, such as custom syntax colors, internationalization support, etc., and some code has not been sorted out, which will look messy. I was going to publish it all after I had written it, but now I don't have time to finish it, so put it here in the hope that it will help others a little.

The new attachment:
« Last Edit: May 07, 2023, 06:06:19 am by tomitomy »

 

TinyPortal © 2005-2018