SynEdit: Handle new Gtk2 IM / Experimental / Issue #38730 / Based on Patch by Do-wan Kim / Moved to new unit

git-svn-id: trunk@65175 -
This commit is contained in:
martin 2021-06-05 22:33:53 +00:00
parent 0d724cb5bb
commit 176f0b3310
8 changed files with 236 additions and 97 deletions

2
.gitattributes vendored
View File

@ -4976,7 +4976,9 @@ components/synedit/languages/syneditstrconst.uk.po svneol=native#text/plain
components/synedit/languages/syneditstrconst.zh_CN.po svneol=native#text/plain components/synedit/languages/syneditstrconst.zh_CN.po svneol=native#text/plain
components/synedit/lazsyneditmousecmdstypes.pp svneol=native#text/pascal components/synedit/lazsyneditmousecmdstypes.pp svneol=native#text/pascal
components/synedit/lazsynedittext.pas svneol=native#text/pascal components/synedit/lazsynedittext.pas svneol=native#text/pascal
components/synedit/lazsyngtk2imm.pas svneol=native#text/pascal
components/synedit/lazsynimm.pas svneol=native#text/pascal components/synedit/lazsynimm.pas svneol=native#text/pascal
components/synedit/lazsynimmbase.pas svneol=native#text/pascal
components/synedit/lazsyntextarea.pp svneol=native#text/pascal components/synedit/lazsyntextarea.pp svneol=native#text/pascal
components/synedit/synbeautifier.pas svneol=native#text/plain components/synedit/synbeautifier.pas svneol=native#text/plain
components/synedit/synbeautifierpascal.pas svneol=native#text/pascal components/synedit/synbeautifierpascal.pas svneol=native#text/pascal

View File

@ -32,7 +32,7 @@ uses
SynHighlighterIni, SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars, SynHighlighterIni, SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars,
SynEditTextSystemCharWidth, SynEditMarkupIfDef, SynPluginMultiCaret, SynEditTextSystemCharWidth, SynEditMarkupIfDef, SynPluginMultiCaret,
synhighlighterpike, SynEditMarkupFoldColoring, SynEditViewedLineMap, synhighlighterpike, SynEditMarkupFoldColoring, SynEditViewedLineMap,
SynEditWrappedView, SynBeautifierPascal, LazarusPackageIntf; SynEditWrappedView, SynBeautifierPascal, LazSynIMMBase, LazarusPackageIntf;
implementation implementation

View File

@ -0,0 +1,79 @@
unit LazSynGtk2IMM;
{$mode objfpc}{$H+}
interface
uses
{$ifdef LCLGtk2}
gtk2, Gtk2Globals,
{$endif}
Classes, SysUtils, Messages, LMessages, LazSynIMMBase, SynEditKeyCmds;
type
{ LazSynImeGtk2 }
LazSynImeGtk2 = class(LazSynIme)
private
FIMESelText: string;
public
procedure WMImeComposition(var Message: TMessage); override;
end;
implementation
uses
SynEdit;
{ LazSynImeGtk2 }
procedure LazSynImeGtk2.WMImeComposition(var Message: TMessage);
{$IFDEF WITH_GTK2_IM}
var
IMStr:string;
i:Integer;
{$ENDIF}
begin
{$IFDEF WITH_GTK2_IM}
if (not FriendEdit.ReadOnly) then
begin
if (Message.WParam and GTK_IM_FLAG_START<>0) then
FIMESelText := FriendEdit.SelText;
// to do : accurate candidate position
// set candidate position
if (Message.WParam and (GTK_IM_FLAG_START or GTK_IM_FLAG_PREEDIT))<>0 then
IM_Context_Set_Cursor_Pos(FriendEdit.CaretXPix,FriendEdit.CaretYPix+FriendEdit.LineHeight);
// valid string at composition & commit
if Message.WParam and (GTK_IM_FLAG_COMMIT or GTK_IM_FLAG_PREEDIT)<>0 then
begin
// insert preedit or commit string
IMStr:=pchar(Message.LParam);
for i:=1 to Length(IMStr) do
TSynEdit(FriendEdit).CommandProcessor(ecChar,IMStr[i],nil);
// select last preedit
if (Message.WParam and GTK_IM_FLAG_COMMIT=0) then
begin
if Length(IMStr)>0 then
for i:=1 to Length(UTF8Decode(IMStr)) do
TSynEdit(FriendEdit).CommandProcessor(ecSelLeft,#0,nil)
end
else
FIMESelText:='';
end;
// end composition
if (Message.WParam and GTK_IM_FLAG_END<>0) and (FIMESelText<>'') then
begin
TSynEdit(FriendEdit).ClearSelection;
// restore selection before preedit.
for i:=1 to Length(FIMESelText) do
TSynEdit(FriendEdit).CommandProcessor(ecChar,FIMESelText[i],nil);
end;
end;
{$ENDIF}
end;
end.

View File

@ -9,7 +9,7 @@ unit LazSynIMM;
interface interface
uses uses
windows, imm, Classes, SysUtils, Controls, LazLoggerBase, LCLType, LazUTF8, Graphics, windows, imm, LazSynIMMBase, Classes, SysUtils, Controls, LazLoggerBase, LCLType, LazUTF8, Graphics,
SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection, SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection,
SynEditMarkup, SynEditTypes, SynEditKeyCmds, LazSynEditText, SynEditTextBase; SynEditMarkup, SynEditTypes, SynEditKeyCmds, LazSynEditText, SynEditTextBase;
@ -20,36 +20,16 @@ const
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
type type
{ LazSynIme } { LazSynWinIme }
LazSynIme = class(TSynEditFriend) LazSynWinIme = class(LazSynIme)
private
FInvalidateLinesMethod: TInvalidateLines;
FOnIMEEnd: TNotifyEvent;
FOnIMEStart: TNotifyEvent;
FIMEActive: Boolean;
protected protected
FInCompose: Boolean; procedure StopIme(Success: Boolean); override;
procedure InvalidateLines(FirstLine, LastLine: integer);
procedure StopIme(Success: Boolean); virtual;
procedure DoIMEStarted;
procedure DoIMEEnded;
public
constructor Create(AOwner: TSynEditBase); reintroduce;
procedure WMImeRequest(var Msg: TMessage); virtual;
procedure WMImeNotify(var Msg: TMessage); virtual;
procedure WMImeComposition(var Msg: TMessage); virtual;
procedure WMImeStartComposition(var Msg: TMessage); virtual;
procedure WMImeEndComposition(var Msg: TMessage); virtual;
procedure FocusKilled; virtual;
property InvalidateLinesMethod : TInvalidateLines write FInvalidateLinesMethod;
property OnIMEStart: TNotifyEvent read FOnIMEStart write FOnIMEStart;
property OnIMEEnd: TNotifyEvent read FOnIMEEnd write FOnIMEEnd;
end; end;
{ LazSynImeSimple } { LazSynImeSimple }
LazSynImeSimple = class(LazSynIme) LazSynImeSimple = class(LazSynWinIme)
private private
FImeBlockSelection: TSynEditSelection; FImeBlockSelection: TSynEditSelection;
FImeWinX, FImeWinY: Integer; FImeWinX, FImeWinY: Integer;
@ -77,7 +57,7 @@ type
{ LazSynImeFull } { LazSynImeFull }
LazSynImeFull = class(LazSynIme) LazSynImeFull = class(LazSynWinIme)
private private
FAdjustLeftCharForTargets: Boolean; FAdjustLeftCharForTargets: Boolean;
FLeftPosForTarget, FRightPosForTarget: Integer; FLeftPosForTarget, FRightPosForTarget: Integer;
@ -116,14 +96,9 @@ type
implementation implementation
{ LazSynIme } { LazSynWinIme }
procedure LazSynIme.InvalidateLines(FirstLine, LastLine: integer); procedure LazSynWinIme.StopIme(Success: Boolean);
begin
FInvalidateLinesMethod(FirstLine, LastLine);
end;
procedure LazSynIme.StopIme(Success: Boolean);
var var
imc: HIMC; imc: HIMC;
begin begin
@ -137,54 +112,7 @@ begin
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ImmReleaseContext(FriendEdit.Handle, imc); ImmReleaseContext(FriendEdit.Handle, imc);
end; end;
DoIMEEnded; inherited StopIme(Success);
end;
procedure LazSynIme.DoIMEStarted;
begin
if FIMEActive then
exit;
FIMEActive := True;
if FOnIMEStart <> nil then
FOnIMEStart(FriendEdit);
end;
procedure LazSynIme.DoIMEEnded;
begin
if not FIMEActive then
exit;
FIMEActive := False;
if FOnIMEEnd <> nil then
FOnIMEEnd(FriendEdit);
end;
constructor LazSynIme.Create(AOwner: TSynEditBase);
begin
FriendEdit := AOwner;
end;
procedure LazSynIme.WMImeRequest(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeNotify(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeStartComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeEndComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.FocusKilled;
begin
end; end;
{ LazSynImeSimple } { LazSynImeSimple }

View File

@ -0,0 +1,101 @@
unit LazSynIMMBase;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Messages, SynEditMiscClasses, SynEditPointClasses;
type
{ LazSynIme }
LazSynIme = class(TSynEditFriend)
private
FInvalidateLinesMethod: TInvalidateLines;
FOnIMEEnd: TNotifyEvent;
FOnIMEStart: TNotifyEvent;
FIMEActive: Boolean;
protected
FInCompose: Boolean;
procedure InvalidateLines(FirstLine, LastLine: integer);
procedure StopIme(Success: Boolean); virtual;
procedure DoIMEStarted;
procedure DoIMEEnded;
public
constructor Create(AOwner: TSynEditBase); reintroduce;
procedure WMImeRequest(var Msg: TMessage); virtual;
procedure WMImeNotify(var Msg: TMessage); virtual;
procedure WMImeComposition(var Msg: TMessage); virtual;
procedure WMImeStartComposition(var Msg: TMessage); virtual;
procedure WMImeEndComposition(var Msg: TMessage); virtual;
procedure FocusKilled; virtual;
property InvalidateLinesMethod : TInvalidateLines write FInvalidateLinesMethod;
property OnIMEStart: TNotifyEvent read FOnIMEStart write FOnIMEStart;
property OnIMEEnd: TNotifyEvent read FOnIMEEnd write FOnIMEEnd;
end;
implementation
{ LazSynIme }
procedure LazSynIme.InvalidateLines(FirstLine, LastLine: integer);
begin
FInvalidateLinesMethod(FirstLine, LastLine);
end;
procedure LazSynIme.StopIme(Success: Boolean);
begin
DoIMEEnded;
end;
procedure LazSynIme.DoIMEStarted;
begin
if FIMEActive then
exit;
FIMEActive := True;
if FOnIMEStart <> nil then
FOnIMEStart(FriendEdit);
end;
procedure LazSynIme.DoIMEEnded;
begin
if not FIMEActive then
exit;
FIMEActive := False;
if FOnIMEEnd <> nil then
FOnIMEEnd(FriendEdit);
end;
constructor LazSynIme.Create(AOwner: TSynEditBase);
begin
FriendEdit := AOwner;
end;
procedure LazSynIme.WMImeRequest(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeNotify(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeStartComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeEndComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.FocusKilled;
begin
end;
end.

View File

@ -379,7 +379,7 @@ If you wish to allow use of your version of these files only under the terms of
</Item> </Item>
<Item> <Item>
<Filename Value="syneditviewedlinemap.pp"/> <Filename Value="syneditviewedlinemap.pp"/>
<UnitName Value="syneditviewedlinemap"/> <UnitName Value="SynEditViewedLineMap"/>
</Item> </Item>
<Item> <Item>
<Filename Value="syneditwrappedview.pp"/> <Filename Value="syneditwrappedview.pp"/>
@ -389,6 +389,15 @@ If you wish to allow use of your version of these files only under the terms of
<Filename Value="synbeautifierpascal.pas"/> <Filename Value="synbeautifierpascal.pas"/>
<UnitName Value="SynBeautifierPascal"/> <UnitName Value="SynBeautifierPascal"/>
</Item> </Item>
<Item>
<Filename Value="lazsyngtk2imm.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="LazSynGtk2IMM"/>
</Item>
<Item>
<Filename Value="lazsynimmbase.pas"/>
<UnitName Value="LazSynIMMBase"/>
</Item>
</Files> </Files>
<LazDoc Paths="docs\xml"/> <LazDoc Paths="docs\xml"/>
<i18n> <i18n>

View File

@ -49,6 +49,7 @@ unit SynEdit;
{$DEFINE WinIMEFull} {$DEFINE WinIMEFull}
{$ENDIF} {$ENDIF}
{$ENDIF} {$ENDIF}
{..$DEFINE Gtk2IME}
{$I synedit.inc} {$I synedit.inc}
@ -102,9 +103,13 @@ interface
{$ENDIF} {$ENDIF}
uses uses
LazSynIMMBase,
{$IFDEF WinIME} {$IFDEF WinIME}
LazSynIMM, LazSynIMM,
{$ENDIF} {$ENDIF}
{$IFDEF Gtk2IME}
LazSynGtk2IMM,
{$ENDIF}
{$IFDEF USE_UTF8BIDI_LCL} {$IFDEF USE_UTF8BIDI_LCL}
FreeBIDI, utf8bidi, FreeBIDI, utf8bidi,
{$ENDIF} {$ENDIF}
@ -426,19 +431,25 @@ type
TCustomSynEdit = class(TSynEditBase) TCustomSynEdit = class(TSynEditBase)
procedure SelAvailChange(Sender: TObject); procedure SelAvailChange(Sender: TObject);
{$IFDEF WinIME}
private private
FImeHandler: LazSynIme; FImeHandler: LazSynIme;
procedure SetImeHandler(AValue: LazSynIme); {$IFDEF Gtk2IME}
protected
procedure GTK_IMComposition(var Message: TMessage); message LM_IM_COMPOSITION;
{$ENDIF}
{$IFDEF WinIME}
private
procedure WMImeRequest(var Msg: TMessage); message WM_IME_REQUEST; procedure WMImeRequest(var Msg: TMessage); message WM_IME_REQUEST;
procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY; procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY;
procedure WMImeStartComposition(var Msg: TMessage); message WM_IME_STARTCOMPOSITION; procedure WMImeStartComposition(var Msg: TMessage); message WM_IME_STARTCOMPOSITION;
procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION; procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
procedure WMImeEndComposition(var Msg: TMessage); message WM_IME_ENDCOMPOSITION; procedure WMImeEndComposition(var Msg: TMessage); message WM_IME_ENDCOMPOSITION;
{$ENDIF}
private
procedure SetImeHandler(AValue: LazSynIme);
protected protected
// SynEdit takes ownership // SynEdit takes ownership
property ImeHandler: LazSynIme read FImeHandler write SetImeHandler; property ImeHandler: LazSynIme read FImeHandler write SetImeHandler;
{$ENDIF}
private private
procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES; procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;
procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND; procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
@ -2323,6 +2334,10 @@ begin
{$ENDIF} {$ENDIF}
FImeHandler.InvalidateLinesMethod := @InvalidateLines; FImeHandler.InvalidateLinesMethod := @InvalidateLines;
{$ENDIF} {$ENDIF}
{$IFDEF Gtk2IME}
FImeHandler := LazSynImeGtk2 .Create(Self);
FImeHandler.InvalidateLinesMethod := @InvalidateLines;
{$ENDIF}
fFontDummy.Name := SynDefaultFontName; fFontDummy.Name := SynDefaultFontName;
fFontDummy.Height := SynDefaultFontHeight; fFontDummy.Height := SynDefaultFontHeight;
@ -2654,9 +2669,7 @@ begin
FreeAndNil(FRightGutterArea); FreeAndNil(FRightGutterArea);
FreeAndNil(FTextArea); FreeAndNil(FTextArea);
FreeAndNil(fTSearch); FreeAndNil(fTSearch);
{$IFDEF WinIME}
FreeAndNil(FImeHandler); FreeAndNil(FImeHandler);
{$ENDIF}
FreeAndNil(fMarkupManager); FreeAndNil(fMarkupManager);
FreeAndNil(fKeyStrokes); FreeAndNil(fKeyStrokes);
FreeAndNil(FMouseActionSearchHandlerList); FreeAndNil(FMouseActionSearchHandlerList);
@ -2894,12 +2907,6 @@ begin
Result := ''; Result := '';
end; end;
{$IFDEF WinIME}
procedure TCustomSynEdit.WMImeRequest(var Msg: TMessage);
begin
FImeHandler.WMImeRequest(Msg);
end;
procedure TCustomSynEdit.SetImeHandler(AValue: LazSynIme); procedure TCustomSynEdit.SetImeHandler(AValue: LazSynIme);
begin begin
if FImeHandler = AValue then Exit; if FImeHandler = AValue then Exit;
@ -2907,6 +2914,19 @@ begin
FImeHandler := AValue; FImeHandler := AValue;
end; end;
{$ifdef Gtk2IME}
procedure TCustomSynEdit.GTK_IMComposition(var Message: TMessage);
begin
FImeHandler.WMImeComposition(Message);
end;
{$endif}
{$IFDEF WinIME}
procedure TCustomSynEdit.WMImeRequest(var Msg: TMessage);
begin
FImeHandler.WMImeRequest(Msg);
end;
procedure TCustomSynEdit.WMImeNotify(var Msg: TMessage); procedure TCustomSynEdit.WMImeNotify(var Msg: TMessage);
begin begin
FImeHandler.WMImeNotify(Msg); FImeHandler.WMImeNotify(Msg);
@ -5133,9 +5153,8 @@ begin
UpdateScreenCaret; UpdateScreenCaret;
if HideSelection and SelAvail then if HideSelection and SelAvail then
Invalidate; Invalidate;
{$IFDEF WinIME} if FImeHandler <> nil then
FImeHandler.FocusKilled; FImeHandler.FocusKilled;
{$ENDIF}
inherited; inherited;
StatusChanged([scFocus]); StatusChanged([scFocus]);
end; end;

View File

@ -43,6 +43,7 @@ interface
{$I ide.inc} {$I ide.inc}
uses uses
LazSynIMMBase,
{$IFDEF WinIME} {$IFDEF WinIME}
LazSynIMM, LazSynIMM,
{$ENDIF} {$ENDIF}