diff --git a/.gitattributes b/.gitattributes
index 0e8672cd4b..3d66bbee1c 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -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
diff --git a/components/synedit/allsynedit.pas b/components/synedit/allsynedit.pas
index c804ec8fa4..03eb2ad055 100644
--- a/components/synedit/allsynedit.pas
+++ b/components/synedit/allsynedit.pas
@@ -32,7 +32,7 @@ uses
SynHighlighterIni, SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars,
SynEditTextSystemCharWidth, SynEditMarkupIfDef, SynPluginMultiCaret,
synhighlighterpike, SynEditMarkupFoldColoring, SynEditViewedLineMap,
- SynEditWrappedView, SynBeautifierPascal, LazarusPackageIntf;
+ SynEditWrappedView, SynBeautifierPascal, LazSynIMMBase, LazarusPackageIntf;
implementation
diff --git a/components/synedit/lazsyngtk2imm.pas b/components/synedit/lazsyngtk2imm.pas
new file mode 100644
index 0000000000..dcec32ce3d
--- /dev/null
+++ b/components/synedit/lazsyngtk2imm.pas
@@ -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.
+
diff --git a/components/synedit/lazsynimm.pas b/components/synedit/lazsynimm.pas
index 057f4bee3a..4d91508c79 100644
--- a/components/synedit/lazsynimm.pas
+++ b/components/synedit/lazsynimm.pas
@@ -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 }
diff --git a/components/synedit/lazsynimmbase.pas b/components/synedit/lazsynimmbase.pas
new file mode 100644
index 0000000000..7972e464bc
--- /dev/null
+++ b/components/synedit/lazsynimmbase.pas
@@ -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.
+
diff --git a/components/synedit/synedit.lpk b/components/synedit/synedit.lpk
index 65bbc240fb..9750c91a65 100644
--- a/components/synedit/synedit.lpk
+++ b/components/synedit/synedit.lpk
@@ -379,7 +379,7 @@ If you wish to allow use of your version of these files only under the terms of
-
-
+
-
@@ -389,6 +389,15 @@ If you wish to allow use of your version of these files only under the terms of
+ -
+
+
+
+
+ -
+
+
+
diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp
index 53e4c1449b..71568f5ce7 100644
--- a/components/synedit/synedit.pp
+++ b/components/synedit/synedit.pp
@@ -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;
diff --git a/ide/sourcesyneditor.pas b/ide/sourcesyneditor.pas
index f3f9b5d56e..0068f2cbc5 100644
--- a/ide/sourcesyneditor.pas
+++ b/ide/sourcesyneditor.pas
@@ -43,6 +43,7 @@ interface
{$I ide.inc}
uses
+ LazSynIMMBase,
{$IFDEF WinIME}
LazSynIMM,
{$ENDIF}