From 82d90431667b61db4aec513db059758e7219b201 Mon Sep 17 00:00:00 2001 From: skalogryz Date: Tue, 25 Nov 2014 05:36:26 +0000 Subject: [PATCH] richmemo: gtk2 text search, partially based on the patch by Krzysztof Dibowski git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3779 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/richmemo/gtk2/gtk2richmemo.pas | 90 ++++++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/components/richmemo/gtk2/gtk2richmemo.pas b/components/richmemo/gtk2/gtk2richmemo.pas index eb08ec5e6..26a5e1d56 100644 --- a/components/richmemo/gtk2/gtk2richmemo.pas +++ b/components/richmemo/gtk2/gtk2richmemo.pas @@ -29,7 +29,7 @@ uses // RTL/FCL Types, Classes, SysUtils, // LCL - LCLType, Controls, Graphics, + LCLType, Controls, Graphics, LazUTF8, // Gtk2 widget Gtk2Def, GTK2WinApiWindow, Gtk2Globals, Gtk2Proc, InterfaceBase, @@ -64,6 +64,8 @@ type class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override; + class function Search(const AWinControl: TWinControl; const ANiddle: string; const SearchOpts: TIntSearchOpt): Integer; override; + class function ImageFromFile(const ARichMemo: TCustomRichMemo; APos: Integer; const FileNameUTF8: string; const AImgSize: TSize @@ -348,7 +350,6 @@ var h : double; fl : double; t : double; - v : Integer; attr : PGtkTextAttributes; fp : TFontParams; const @@ -407,6 +408,91 @@ begin gtk_text_buffer_insert(b, @istart, @textUTF8[1], length(TextUTF8)); end; +procedure UTF8CharsToWideString(const p: Pchar; var w: WideString); +var + slen : Integer; + cnt: Integer; + sz: SizeUInt; +begin + if not Assigned(p) then begin + w:=''; + Exit; + end; + slen:=strlen(p); + if slen=0 then begin + w:=''; + Exit; + end; + cnt:=UTF8Length(p, slen); + SetLength(w, cnt); + if cnt>0 then + ConvertUTF8ToUTF16( @w[1], length(w), p, slen, [toInvalidCharToSymbol], sz); + SetLength(w, sz); +end; + +class function TGtk2WSCustomRichMemo.Search(const AWinControl: TWinControl; + const ANiddle: string; const SearchOpts: TIntSearchOpt): Integer; +var + TextWidget : PGtkWidget; + buffer : PGtkTextBuffer; + istart : TGtkTextIter; + iend : TGtkTextIter; + start_match : TGtkTextIter; + end_match : TGtkTextIter; + Found : Boolean; + opt : TGtkTextSearchFlags; + gstr : PChar; + txt : WideString; + sub : WIdeString; +const + GTK_TEXT_SEARCH_VISIBLE_ONLY = 1 shl 0; (* values of TGtkTextSearchFlags *) + {%H-}GTK_TEXT_SEARCH_TEXT_ONLY = 1 shl 1; + GTK_TEXT_SEARCH_CASE_INSENSITIVE = 1 shl 2; +begin + Result := -1; + GetWidgetBuffer(AWinControl, TextWidget, buffer); + if not Assigned(buffer) then Exit; + + opt:=GTK_TEXT_SEARCH_VISIBLE_ONLY; + if not (soMatchCase in SearchOpts.Options) then begin + opt:=opt or GTK_TEXT_SEARCH_CASE_INSENSITIVE; // doesn't work anyway! it works in gtk3 only + + gtk_text_buffer_get_iter_at_offset (buffer, @istart, SearchOpts.start); + gtk_text_buffer_get_iter_at_offset (buffer, @iend, SearchOpts.start+SearchOpts.len); + + gtk_text_buffer_get_text(buffer, @istart, @iend, false); + gstr := gtk_text_buffer_get_text(Buffer, @istart, @iend, False); + if Assigned(gstr) then begin + UTF8CharsToWideString(gstr, txt); + g_free(gstr); + txt:=WideUpperCase(txt); + sub:=WideUpperCase(UTF8Decode(ANiddle)); + Result:=Pos(sub,txt); + if Result>0 then + Result:=Result-1+SearchOpts.start + else + Result:=-1; + end else + Result:=-1; + end else begin + gtk_text_buffer_get_iter_at_offset(buffer, @istart, SearchOpts.start ); + if not (soBackward in SearchOpts.Options) then + begin + gtk_text_buffer_get_iter_at_offset(buffer, @iend, SearchOpts.start+SearchOpts.len ); + Found := gtk_text_iter_forward_search(@istart, PgChar(ANiddle), opt, + @start_match, @end_match, @iend) + end else begin + gtk_text_buffer_get_iter_at_offset(buffer, @iend, SearchOpts.start-SearchOpts.len); + Found := gtk_text_iter_backward_search(@istart, PgChar(ANiddle), opt, + @start_match, @end_match, @iend) + end; + + if Found + then Result := gtk_text_iter_get_offset(@start_match) + else Result := -1; + end; +end; + class function TGtk2WSCustomRichMemo.ImageFromFile( const ARichMemo: TCustomRichMemo; APos: Integer; const FileNameUTF8: string; const AImgSize: TSize): Boolean;