diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 55bc9b8..eb9b6fe 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2178,6 +2178,172 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) return FALSE; } +static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, + LPARAM flags, BOOL unicode) +{ + WCHAR wstr; + + if (unicode) + wstr = (WCHAR)charCode; + else + { + CHAR charA = charCode; + MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1); + } + + if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) { + MessageBeep(MB_ICONERROR); + return 0; /* FIXME really 0 ? */ + } + + if (((unsigned)wstr)>=' ' + || (wstr=='\r' && (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE)) + || wstr=='\t') { + ME_Cursor cursor = editor->pCursors[0]; + ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); + int from, to; + BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; + ME_GetSelection(editor, &from, &to); + if (wstr=='\t' + /* v4.1 allows tabs to be inserted with ctrl key down */ + && !(ctrl_is_down && !editor->bEmulateVersion10) + ) + { + ME_DisplayItem *para; + BOOL bSelectedRow = FALSE; + + para = ME_GetParagraph(cursor.pRun); + if (ME_IsSelection(editor) && + cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && + to == ME_GetCursorOfs(editor, 0) && + para->member.para.prev_para->type == diParagraph) + { + para = para->member.para.prev_para; + bSelectedRow = TRUE; + } + if (ME_IsInTable(para)) + { + ME_TabPressedInTable(editor, bSelectedRow); + ME_CommitUndo(editor); + return 0; + } + } else if (!editor->bEmulateVersion10) { /* v4.1 */ + if (para->member.para.nFlags & MEPF_ROWEND) { + if (wstr=='\r') { + /* Add a new table row after this row. */ + para = ME_AppendTableRow(editor, para); + para = para->member.para.next_para; + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + ME_CommitUndo(editor); + ME_CheckTablesForCorruption(editor); + ME_UpdateRepaint(editor); + return 0; + } else if (from == to) { + para = para->member.para.next_para; + if (para->member.para.nFlags & MEPF_ROWSTART) + para = para->member.para.next_para; + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + } + } + else if (para == ME_GetParagraph(editor->pCursors[1].pRun) && + cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 && + para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART && + !para->member.para.prev_para->member.para.nCharOfs) + { + /* Insert a newline before the table. */ + WCHAR endl = '\r'; + para = para->member.para.prev_para; + para->member.para.nFlags &= ~MEPF_ROWSTART; + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[1] = editor->pCursors[0]; + ME_InsertTextFromCursor(editor, 0, &endl, 1, + editor->pCursors[0].pRun->member.run.style); + para = editor->pBuffer->pFirst->member.para.next_para; + ME_SetDefaultParaFormat(para->member.para.pFmt); + para->member.para.nFlags = MEPF_REWRAP; + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[1] = editor->pCursors[0]; + para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART; + ME_CommitCoalescingUndo(editor); + ME_CheckTablesForCorruption(editor); + ME_UpdateRepaint(editor); + return 0; + } + } else { /* v1.0 - 3.0 */ + ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); + if (ME_IsInTable(cursor.pRun)) + { + if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) + { + if (from == to) { + if (wstr=='\r') { + ME_ContinueCoalescingTransaction(editor); + para = ME_AppendTableRow(editor, para); + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + ME_CommitCoalescingUndo(editor); + ME_UpdateRepaint(editor); + } else { + /* Text should not be inserted at the end of the table. */ + MessageBeep(-1); + } + return 0; + } + } else if (wstr == '\r') { + ME_ContinueCoalescingTransaction(editor); + if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && + !ME_IsInTable(para->member.para.prev_para)) + { + /* Insert newline before table */ + WCHAR endl = '\r'; + cursor.pRun = ME_FindItemBack(para, diRun); + if (cursor.pRun) + editor->pCursors[0].pRun = cursor.pRun; + editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + ME_InsertTextFromCursor(editor, 0, &endl, 1, + editor->pCursors[0].pRun->member.run.style); + } else { + editor->pCursors[1] = editor->pCursors[0]; + para = ME_AppendTableRow(editor, para); + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + } + ME_CommitCoalescingUndo(editor); + ME_UpdateRepaint(editor); + return 0; + } + } + } + /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */ + /* WM_CHAR is restricted to nTextLimit */ + if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from)) + { + ME_Style *style = ME_GetInsertStyle(editor, 0); + ME_SaveTempStyle(editor); + ME_ContinueCoalescingTransaction(editor); + if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000)) + ME_InsertEndRowFromCursor(editor, 0); + else + ME_InsertTextFromCursor(editor, 0, &wstr, 1, style); + ME_ReleaseStyle(style); + ME_CommitCoalescingUndo(editor); + SetCursor(NULL); + } + + if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); + + ME_UpdateRepaint(editor); + } + return 0; +} + /* Process the message and calculate the new click count. * * returns: The click count if it is mouse down event, else returns 0. */ @@ -3683,170 +3849,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, if (ME_KeyDown(editor, LOWORD(wParam))) return 0; goto do_default; - case WM_CHAR: - { - WCHAR wstr; - - if (unicode) - wstr = (WCHAR)wParam; - else - { - CHAR charA = wParam; - MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1); - } - - if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) { - MessageBeep(MB_ICONERROR); - return 0; /* FIXME really 0 ? */ - } - - if (((unsigned)wstr)>=' ' - || (wstr=='\r' && (GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE)) - || wstr=='\t') { - ME_Cursor cursor = editor->pCursors[0]; - ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); - int from, to; - BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; - ME_GetSelection(editor, &from, &to); - if (wstr=='\t' - /* v4.1 allows tabs to be inserted with ctrl key down */ - && !(ctrl_is_down && !editor->bEmulateVersion10) - ) - { - ME_DisplayItem *para; - BOOL bSelectedRow = FALSE; - - para = ME_GetParagraph(cursor.pRun); - if (ME_IsSelection(editor) && - cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && - to == ME_GetCursorOfs(editor, 0) && - para->member.para.prev_para->type == diParagraph) - { - para = para->member.para.prev_para; - bSelectedRow = TRUE; - } - if (ME_IsInTable(para)) - { - ME_TabPressedInTable(editor, bSelectedRow); - ME_CommitUndo(editor); - return 0; - } - } else if (!editor->bEmulateVersion10) { /* v4.1 */ - if (para->member.para.nFlags & MEPF_ROWEND) { - if (wstr=='\r') { - /* Add a new table row after this row. */ - para = ME_AppendTableRow(editor, para); - para = para->member.para.next_para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - editor->pCursors[1] = editor->pCursors[0]; - ME_CommitUndo(editor); - ME_CheckTablesForCorruption(editor); - ME_UpdateRepaint(editor); - return 0; - } else if (from == to) { - para = para->member.para.next_para; - if (para->member.para.nFlags & MEPF_ROWSTART) - para = para->member.para.next_para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - editor->pCursors[1] = editor->pCursors[0]; - } - } - else if (para == ME_GetParagraph(editor->pCursors[1].pRun) && - cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 && - para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART && - !para->member.para.prev_para->member.para.nCharOfs) - { - /* Insert a newline before the table. */ - WCHAR endl = '\r'; - para = para->member.para.prev_para; - para->member.para.nFlags &= ~MEPF_ROWSTART; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, - editor->pCursors[0].pRun->member.run.style); - para = editor->pBuffer->pFirst->member.para.next_para; - ME_SetDefaultParaFormat(para->member.para.pFmt); - para->member.para.nFlags = MEPF_REWRAP; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[1] = editor->pCursors[0]; - para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART; - ME_CommitCoalescingUndo(editor); - ME_CheckTablesForCorruption(editor); - ME_UpdateRepaint(editor); - return 0; - } - } else { /* v1.0 - 3.0 */ - ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); - if (ME_IsInTable(cursor.pRun)) - { - if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) - { - if (from == to) { - if (wstr=='\r') { - ME_ContinueCoalescingTransaction(editor); - para = ME_AppendTableRow(editor, para); - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - editor->pCursors[1] = editor->pCursors[0]; - ME_CommitCoalescingUndo(editor); - ME_UpdateRepaint(editor); - } else { - /* Text should not be inserted at the end of the table. */ - MessageBeep(-1); - } - return 0; - } - } else if (wstr == '\r') { - ME_ContinueCoalescingTransaction(editor); - if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && - !ME_IsInTable(para->member.para.prev_para)) - { - /* Insert newline before table */ - WCHAR endl = '\r'; - cursor.pRun = ME_FindItemBack(para, diRun); - if (cursor.pRun) - editor->pCursors[0].pRun = cursor.pRun; - editor->pCursors[0].nOffset = 0; - editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, - editor->pCursors[0].pRun->member.run.style); - } else { - editor->pCursors[1] = editor->pCursors[0]; - para = ME_AppendTableRow(editor, para); - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - editor->pCursors[1] = editor->pCursors[0]; - } - ME_CommitCoalescingUndo(editor); - ME_UpdateRepaint(editor); - return 0; - } - } - } - /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */ - /* WM_CHAR is restricted to nTextLimit */ - if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from)) - { - ME_Style *style = ME_GetInsertStyle(editor, 0); - ME_SaveTempStyle(editor); - ME_ContinueCoalescingTransaction(editor); - if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000)) - ME_InsertEndRowFromCursor(editor, 0); - else - ME_InsertTextFromCursor(editor, 0, &wstr, 1, style); - ME_ReleaseStyle(style); - ME_CommitCoalescingUndo(editor); - SetCursor(NULL); - } - - if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); - - ME_UpdateRepaint(editor); - } - return 0; - } + case WM_CHAR: + return ME_Char(editor, wParam, lParam, unicode); case WM_UNICHAR: if (unicode) { @@ -3856,10 +3860,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, if(wParam > 0xffff) /* convert to surrogates */ { wParam -= 0x10000; - SendMessageW(editor->hWnd, WM_CHAR, (wParam >> 10) + 0xd800, 0); - SendMessageW(editor->hWnd, WM_CHAR, (wParam & 0x03ff) + 0xdc00, 0); + ME_Char(editor, (wParam >> 10) + 0xd800, 0, TRUE); + ME_Char(editor, (wParam & 0x03ff) + 0xdc00, 0, TRUE); + } else { + ME_Char(editor, wParam, 0, TRUE); } - else SendMessageW(editor->hWnd, WM_CHAR, wParam, 0); } return 0; }