Thank you for your kind explanation.
freezing undo is very dangerous.
Your are absolutely right.
I am sorry for tentative.patch is above myself.
Instead of droping undos, I have reimplemented it by coalescing undos.
To coalesce undo steps between WM_IME_STARTCOMPOSITION and
WM_IME_ENDCOMPOSITION,
I have touched the variable mayCoalesce under BeginUndoAction and
EndUndoAction in CellBuffer.cxx.
I changed only the variable mayCoalesce to be true.
For flexible testing, I changed the names:
the methods BeginUndoCoalesce, EndUndoCoalesce and the variable
mayContinuing respectively.
This is the patch.
I think my patched methods may help implementing IME on the spot.
Please take a look.
====================================================================
Replace this function. This the main part.
file : ScintillaWin.cxx
----------------------------------------------------------------------------------------------------------------------------
sptr_t ScintillaWin::HandleComposition(uptr_t wParam, sptr_t lParam) {
bool koreanIME = (InputCodePage() == 949 || InputCodePage() == 1361);
if (koreanIME) {
// copy & paste by johnsonj
// Great thanks to
// jiniya from http://www.jiniya.net/tt/494 for DBCS input with
AddCharUTF()
// BLUEnLIVE from http://zockr.tistory.com/1118 for UNDO and
inOverstrike
HIMC hIMC = ::ImmGetContext(MainHWND());
if (!hIMC) {
return 0;
}
const int maxLenInputIME = 4;
wchar_t wcs[maxLenInputIME];
int wides = 0;
char hanval[maxLenInputIME];
unsigned int hanlen = 0;
bool tmpOverstrike = inOverstrike; // for avoiding inOverstrike
condition in AddCharUTF()
if (compstrExist) {
pdoc->BeginUndoCoalesce(true);
for (size_t r = 0; r < sel.Count(); r++) {
pdoc->DelChar(sel.Range(r).caret.Position());
}
pdoc->EndUndoCoalesce(true);
}
if (lParam & GCS_COMPSTR) {
long bytes = ::ImmGetCompositionStringW
(hIMC, GCS_COMPSTR, wcs, maxLenInputIME);
wides = bytes / 2;
inOverstrike = inOverstrike && (!compstrExist);
compstrExist = (wides != 0);
} else if (lParam & GCS_RESULTSTR) {
long bytes = ::ImmGetCompositionStringW
(hIMC, GCS_RESULTSTR, wcs, maxLenInputIME);
wides = bytes / 2;
compstrExist = (wides == 0);
inOverstrike = inOverstrike && (wides >= 2);
}
if (wides >= 1) {
if (IsUnicodeMode()) {
hanlen = UTF8Length(wcs, wides);
UTF8FromUTF16(wcs, wides, hanval, hanlen);
hanval[hanlen] = '\0';
} else {
hanlen = ::WideCharToMultiByte(InputCodePage() , 0
, wcs , wides , hanval ,
sizeof(hanval) - 1 , 0 , 0);
hanval[hanlen] = '\0';
}
if (compstrExist) {
vs.caretStyle = CARETSTYLE_BLOCK;
bool tmpRecordingMacro = recordingMacro;
recordingMacro = false;
pdoc->BeginUndoCoalesce(true);
AddCharUTF(hanval, hanlen, true);
pdoc->BeginUndoCoalesce(true);
recordingMacro = tmpRecordingMacro;
AutoCompleteCharacterDeleted();
Editor::NotifyChar((static_cast<unsigned char>(hanval[0])
<< 8) |
static_cast<unsigned char>(hanval[1]));
for (size_t r = 0; r < sel.Count(); r++) {
int positionInsert = sel.Range(r).Start().Position();
sel.Range(r).caret.SetPosition(positionInsert - hanlen);
sel.Range(r).anchor.SetPosition(positionInsert -
hanlen);
}
} else {
pdoc->BeginUndoCoalesce(true);
AddCharUTF(hanval, hanlen, true);
pdoc->BeginUndoCoalesce(true);
}
}
// set the candidate window position for HANJA
// have to be moved to WM_IME_NOTIFY
Point pos = PointMainCaret();
CANDIDATEFORM CandForm;
CandForm.dwIndex = 0;
CandForm.dwStyle = CFS_CANDIDATEPOS;
CandForm.ptCurrentPos.x = static_cast<int>(pos.x);
CandForm.ptCurrentPos.y = static_cast<int>(pos.y + vs.lineHeight);
::ImmSetCandidateWindow(hIMC, &CandForm);
ShowCaretAtCurrentPosition();
inOverstrike = tmpOverstrike;
::ImmReleaseContext(MainHWND(), hIMC);
return 0;
} else { // original code follows for other IMEs
if (lParam & GCS_RESULTSTR) {
HIMC hIMC = ::ImmGetContext(MainHWND());
if (hIMC) {
const int maxLenInputIME = 200;
wchar_t wcs[maxLenInputIME];
LONG bytes = ::ImmGetCompositionStringW(hIMC,
GCS_RESULTSTR, wcs, (maxLenInputIME-1)*2);
int wides = bytes / 2;
if (IsUnicodeMode()) {
char utfval[maxLenInputIME * 3];
unsigned int len = UTF8Length(wcs, wides);
UTF8FromUTF16(wcs, wides, utfval, len);
utfval[len] = '\0';
AddCharUTF(utfval, len);
} else {
char dbcsval[maxLenInputIME * 2];
int size = ::WideCharToMultiByte(InputCodePage(),
0, wcs, wides, dbcsval, sizeof(dbcsval) - 1, 0, 0);
for (int i=0; i<size; i++) {
AddChar(dbcsval[i]);
}
}
// Set new position after converted
Point pos = PointMainCaret();
COMPOSITIONFORM CompForm;
CompForm.dwStyle = CFS_POINT;
CompForm.ptCurrentPos.x = static_cast<int>(pos.x);
CompForm.ptCurrentPos.y = static_cast<int>(pos.y);
::ImmSetCompositionWindow(hIMC, &CompForm);
::ImmReleaseContext(MainHWND(), hIMC);
}
return 0;
}
return ::DefWindowProc(MainHWND(), WM_IME_COMPOSITION, wParam,
lParam);
}
}
Replace these conditions.
--------------------------------------------------------------------------------------------------------------------
case WM_IME_STARTCOMPOSITION: { // dbcs
bool koreanIME = (InputCodePage() == 949 || InputCodePage() ==
1361);
if (koreanIME) { //by johnsonj
tmpCaretStyle = vs.caretStyle;
if (vs.caretStyle > CARETSTYLE_BLOCK) {
vs.caretStyle= CARETSTYLE_LINE;
}
return ::DefWindowProc(MainHWND(), iMessage, wParam,
lParam);
}
ImeStartComposition();
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
case WM_IME_ENDCOMPOSITION: { // dbcs
bool koreanIME = (InputCodePage() == 949 || InputCodePage() ==
1361);
if (koreanIME) { // by johnsonj
vs.caretStyle = tmpCaretStyle;
}
ImeEndComposition();
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
====================================================================
file : ScintillaWin.cxx
under : class ScintillaWin :
int tmpCaretStyle; // by johnsonj
bool compstrExist; //by johnsonj
under : ScintillaWin::ScintillaWin(HWND hwnd) {
tmpCaretStyle = 0; // by johnsonj
compstrExist = false; //by johnsonj
=====================================================================
file : CellBuffer.cxx
under : class CellBuffer {
void BeginUndoCoalesce(bool mayContinuing); //by johnsonj
void EndUndoCoalesce(bool mayContinuing); //by johnsonj
under : class UndoHistory {
void BeginUndoCoalesce(bool mayContinuing); //by johnsonj
void EndUndoCoalesce(bool mayContinuing); //by johnsonj
====================================================================
file : CellBuffer.h
void CellBuffer::BeginUndoCoalesce(bool mayContinuing) { //by johnsonj
uh.BeginUndoCoalesce(mayContinuing);
}
void CellBuffer::EndUndoCoalesce(bool mayContinuing) { //by johnsonj
uh.EndUndoCoalesce(mayContinuing);
}
=====================================================================
file : Document.h
under : class Document : PerLine, public IDocumentWithLineEnd, public
ILoader
void BeginUndoCoalesce(bool mayContinuing) {
cb.BeginUndoCoalesce(mayContinuing); } //by johnsonj
void EndUndoCoalesce(bool mayContinuing)
{cb.EndUndoCoalesce(mayContinuing); } //by johnsonj
--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-interest+***@googlegroups.com.
To post to this group, send email to scintilla-***@googlegroups.com.
Visit this group at http://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/d/optout.