mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 04:16:06 +02:00
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:
parent
0d724cb5bb
commit
176f0b3310
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -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/lazsyneditmousecmdstypes.pp 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/lazsynimmbase.pas svneol=native#text/pascal
|
||||
components/synedit/lazsyntextarea.pp svneol=native#text/pascal
|
||||
components/synedit/synbeautifier.pas svneol=native#text/plain
|
||||
components/synedit/synbeautifierpascal.pas svneol=native#text/pascal
|
||||
|
@ -32,7 +32,7 @@ uses
|
||||
SynHighlighterIni, SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars,
|
||||
SynEditTextSystemCharWidth, SynEditMarkupIfDef, SynPluginMultiCaret,
|
||||
synhighlighterpike, SynEditMarkupFoldColoring, SynEditViewedLineMap,
|
||||
SynEditWrappedView, SynBeautifierPascal, LazarusPackageIntf;
|
||||
SynEditWrappedView, SynBeautifierPascal, LazSynIMMBase, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
79
components/synedit/lazsyngtk2imm.pas
Normal file
79
components/synedit/lazsyngtk2imm.pas
Normal 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.
|
||||
|
@ -9,7 +9,7 @@ unit LazSynIMM;
|
||||
interface
|
||||
|
||||
uses
|
||||
windows, imm, Classes, SysUtils, Controls, LazLoggerBase, LCLType, LazUTF8, Graphics,
|
||||
windows, imm, LazSynIMMBase, Classes, SysUtils, Controls, LazLoggerBase, LCLType, LazUTF8, Graphics,
|
||||
SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection,
|
||||
SynEditMarkup, SynEditTypes, SynEditKeyCmds, LazSynEditText, SynEditTextBase;
|
||||
|
||||
@ -20,36 +20,16 @@ const
|
||||
{$ENDIF}{$ENDIF}
|
||||
type
|
||||
|
||||
{ LazSynIme }
|
||||
{ LazSynWinIme }
|
||||
|
||||
LazSynIme = class(TSynEditFriend)
|
||||
private
|
||||
FInvalidateLinesMethod: TInvalidateLines;
|
||||
FOnIMEEnd: TNotifyEvent;
|
||||
FOnIMEStart: TNotifyEvent;
|
||||
FIMEActive: Boolean;
|
||||
LazSynWinIme = class(LazSynIme)
|
||||
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;
|
||||
procedure StopIme(Success: Boolean); override;
|
||||
end;
|
||||
|
||||
{ LazSynImeSimple }
|
||||
|
||||
LazSynImeSimple = class(LazSynIme)
|
||||
LazSynImeSimple = class(LazSynWinIme)
|
||||
private
|
||||
FImeBlockSelection: TSynEditSelection;
|
||||
FImeWinX, FImeWinY: Integer;
|
||||
@ -77,7 +57,7 @@ type
|
||||
|
||||
{ LazSynImeFull }
|
||||
|
||||
LazSynImeFull = class(LazSynIme)
|
||||
LazSynImeFull = class(LazSynWinIme)
|
||||
private
|
||||
FAdjustLeftCharForTargets: Boolean;
|
||||
FLeftPosForTarget, FRightPosForTarget: Integer;
|
||||
@ -116,14 +96,9 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
{ LazSynIme }
|
||||
{ LazSynWinIme }
|
||||
|
||||
procedure LazSynIme.InvalidateLines(FirstLine, LastLine: integer);
|
||||
begin
|
||||
FInvalidateLinesMethod(FirstLine, LastLine);
|
||||
end;
|
||||
|
||||
procedure LazSynIme.StopIme(Success: Boolean);
|
||||
procedure LazSynWinIme.StopIme(Success: Boolean);
|
||||
var
|
||||
imc: HIMC;
|
||||
begin
|
||||
@ -137,54 +112,7 @@ begin
|
||||
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
||||
ImmReleaseContext(FriendEdit.Handle, imc);
|
||||
end;
|
||||
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
|
||||
inherited StopIme(Success);
|
||||
end;
|
||||
|
||||
{ LazSynImeSimple }
|
||||
|
101
components/synedit/lazsynimmbase.pas
Normal file
101
components/synedit/lazsynimmbase.pas
Normal 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.
|
||||
|
@ -379,7 +379,7 @@ If you wish to allow use of your version of these files only under the terms of
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="syneditviewedlinemap.pp"/>
|
||||
<UnitName Value="syneditviewedlinemap"/>
|
||||
<UnitName Value="SynEditViewedLineMap"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<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"/>
|
||||
<UnitName Value="SynBeautifierPascal"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="lazsyngtk2imm.pas"/>
|
||||
<AddToUsesPkgSection Value="False"/>
|
||||
<UnitName Value="LazSynGtk2IMM"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="lazsynimmbase.pas"/>
|
||||
<UnitName Value="LazSynIMMBase"/>
|
||||
</Item>
|
||||
</Files>
|
||||
<LazDoc Paths="docs\xml"/>
|
||||
<i18n>
|
||||
|
@ -49,6 +49,7 @@ unit SynEdit;
|
||||
{$DEFINE WinIMEFull}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{..$DEFINE Gtk2IME}
|
||||
|
||||
{$I synedit.inc}
|
||||
|
||||
@ -102,9 +103,13 @@ interface
|
||||
{$ENDIF}
|
||||
|
||||
uses
|
||||
LazSynIMMBase,
|
||||
{$IFDEF WinIME}
|
||||
LazSynIMM,
|
||||
{$ENDIF}
|
||||
{$IFDEF Gtk2IME}
|
||||
LazSynGtk2IMM,
|
||||
{$ENDIF}
|
||||
{$IFDEF USE_UTF8BIDI_LCL}
|
||||
FreeBIDI, utf8bidi,
|
||||
{$ENDIF}
|
||||
@ -426,19 +431,25 @@ type
|
||||
|
||||
TCustomSynEdit = class(TSynEditBase)
|
||||
procedure SelAvailChange(Sender: TObject);
|
||||
{$IFDEF WinIME}
|
||||
private
|
||||
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 WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY;
|
||||
procedure WMImeStartComposition(var Msg: TMessage); message WM_IME_STARTCOMPOSITION;
|
||||
procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
|
||||
procedure WMImeEndComposition(var Msg: TMessage); message WM_IME_ENDCOMPOSITION;
|
||||
{$ENDIF}
|
||||
private
|
||||
procedure SetImeHandler(AValue: LazSynIme);
|
||||
protected
|
||||
// SynEdit takes ownership
|
||||
property ImeHandler: LazSynIme read FImeHandler write SetImeHandler;
|
||||
{$ENDIF}
|
||||
private
|
||||
procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;
|
||||
procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
|
||||
@ -2323,6 +2334,10 @@ begin
|
||||
{$ENDIF}
|
||||
FImeHandler.InvalidateLinesMethod := @InvalidateLines;
|
||||
{$ENDIF}
|
||||
{$IFDEF Gtk2IME}
|
||||
FImeHandler := LazSynImeGtk2 .Create(Self);
|
||||
FImeHandler.InvalidateLinesMethod := @InvalidateLines;
|
||||
{$ENDIF}
|
||||
|
||||
fFontDummy.Name := SynDefaultFontName;
|
||||
fFontDummy.Height := SynDefaultFontHeight;
|
||||
@ -2654,9 +2669,7 @@ begin
|
||||
FreeAndNil(FRightGutterArea);
|
||||
FreeAndNil(FTextArea);
|
||||
FreeAndNil(fTSearch);
|
||||
{$IFDEF WinIME}
|
||||
FreeAndNil(FImeHandler);
|
||||
{$ENDIF}
|
||||
FreeAndNil(fMarkupManager);
|
||||
FreeAndNil(fKeyStrokes);
|
||||
FreeAndNil(FMouseActionSearchHandlerList);
|
||||
@ -2894,12 +2907,6 @@ begin
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
{$IFDEF WinIME}
|
||||
procedure TCustomSynEdit.WMImeRequest(var Msg: TMessage);
|
||||
begin
|
||||
FImeHandler.WMImeRequest(Msg);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetImeHandler(AValue: LazSynIme);
|
||||
begin
|
||||
if FImeHandler = AValue then Exit;
|
||||
@ -2907,6 +2914,19 @@ begin
|
||||
FImeHandler := AValue;
|
||||
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);
|
||||
begin
|
||||
FImeHandler.WMImeNotify(Msg);
|
||||
@ -5133,9 +5153,8 @@ begin
|
||||
UpdateScreenCaret;
|
||||
if HideSelection and SelAvail then
|
||||
Invalidate;
|
||||
{$IFDEF WinIME}
|
||||
FImeHandler.FocusKilled;
|
||||
{$ENDIF}
|
||||
if FImeHandler <> nil then
|
||||
FImeHandler.FocusKilled;
|
||||
inherited;
|
||||
StatusChanged([scFocus]);
|
||||
end;
|
||||
|
@ -43,6 +43,7 @@ interface
|
||||
{$I ide.inc}
|
||||
|
||||
uses
|
||||
LazSynIMMBase,
|
||||
{$IFDEF WinIME}
|
||||
LazSynIMM,
|
||||
{$ENDIF}
|
||||
|
Loading…
Reference in New Issue
Block a user