From 4c462c38769e36f9da06e72feb50b3f7c1950944 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 10 Sep 2008 13:35:44 +0000 Subject: [PATCH] sync riched20 to wine 1.1.4 svn path=/trunk/; revision=36125 --- reactos/dll/win32/riched20/editor.c | 94 ++++++++++++++++++++++++++++- reactos/dll/win32/riched20/editor.h | 5 +- reactos/dll/win32/riched20/table.c | 46 ++++++-------- reactos/dll/win32/riched20/wrap.c | 2 +- 4 files changed, 116 insertions(+), 31 deletions(-) diff --git a/reactos/dll/win32/riched20/editor.c b/reactos/dll/win32/riched20/editor.c index aa5938326a3..adc9362907f 100644 --- a/reactos/dll/win32/riched20/editor.c +++ b/reactos/dll/win32/riched20/editor.c @@ -1410,6 +1410,28 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre style = ME_GetSelectionInsertStyle(editor); ME_InternalDeleteText(editor, from, to-from, FALSE); + + /* Don't insert text at the end of the table row */ + if (!editor->bEmulateVersion10) { /* v4.1 */ + ME_DisplayItem *para = ME_GetParagraph(editor->pCursors->pRun); + if (para->member.para.nFlags & MEPF_ROWEND) + { + para = para->member.para.next_para; + editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[0].nOffset = 0; + } + 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 { /* v1.0 - 3.0 */ + if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA && + ME_IsInTable(editor->pCursors[0].pRun)) + return 0; + } } else { ME_DisplayItem *para_item; @@ -3663,6 +3685,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, 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); @@ -3671,13 +3695,13 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, && !(ctrl_is_down && !editor->bEmulateVersion10) ) { - ME_Cursor cursor = editor->pCursors[0]; 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; @@ -3689,6 +3713,74 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ME_CommitUndo(editor); return 0; } + } else if (!editor->bEmulateVersion10) { /* v4.1 */ + if (para->member.para.nFlags & MEPF_ROWEND) { + if (wstr=='\r') { + /* FIXME: Add a new table row after this row. */ + 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) + { + /* FIXME: Insert a newline before the table. */ + } + } 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 */ diff --git a/reactos/dll/win32/riched20/editor.h b/reactos/dll/win32/riched20/editor.h index 5e6f4cb502c..b9c01b790d5 100644 --- a/reactos/dll/win32/riched20/editor.h +++ b/reactos/dll/win32/riched20/editor.h @@ -23,7 +23,7 @@ extern HANDLE me_heap; -static inline void *heap_alloc( size_t len ) +static inline void __WINE_ALLOC_SIZE(1) *heap_alloc( size_t len ) { return HeapAlloc( me_heap, 0, len ); } @@ -33,7 +33,7 @@ static inline BOOL heap_free( void *ptr ) return HeapFree( me_heap, 0, ptr ); } -static inline void *heap_realloc( void *ptr, size_t len ) +static inline void __WINE_ALLOC_SIZE(2) *heap_realloc( void *ptr, size_t len ) { return HeapReAlloc( me_heap, 0, ptr, len ); } @@ -296,6 +296,7 @@ ME_DisplayItem *ME_GetTableRowEnd(ME_DisplayItem *para); ME_DisplayItem *ME_GetTableRowStart(ME_DisplayItem *para); void ME_CheckTablesForCorruption(ME_TextEditor *editor); void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars); +ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, ME_DisplayItem *table_row); void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow); struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor); void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef); diff --git a/reactos/dll/win32/riched20/table.c b/reactos/dll/win32/riched20/table.c index 248ea11719f..9cb4bbffd65 100644 --- a/reactos/dll/win32/riched20/table.c +++ b/reactos/dll/win32/riched20/table.c @@ -29,7 +29,7 @@ * Richedit version 1.0 - 3.0: * Tables are implemented in these versions using tabs at the end of cells, * and tab stops to position the cells. The paragraph format flag PFE_TABLE - * will indicate the the paragraph is a table row. Note that in this + * will indicate that the paragraph is a table row. Note that in this * implementation there is one paragraph per table row. * * Richedit version 4.1: @@ -37,7 +37,7 @@ * each with it's own paragraph format, and cells may even contain tables * nested within the cell. * - * There are is also a paragraph at the start of each table row that contains + * There is also a paragraph at the start of each table row that contains * the rows paragraph format (e.g. to change the row alignment to row), and a * paragraph at the end of the table row with the PFE_TABLEROWDELIMITER flag * set. The paragraphs at the start and end of the table row should always be @@ -345,7 +345,7 @@ void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars) ME_DisplayItem *pRun; int nCharsToBoundary; - if (this_para->member.para.nCharOfs != nOfs && + if ((this_para->member.para.nCharOfs != nOfs || this_para == end_para) && this_para->member.para.pFmt->dwMask & PFM_TABLE && this_para->member.para.pFmt->wEffects & PFE_TABLE) { @@ -360,27 +360,13 @@ void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars) } else if (end_para->member.para.pFmt->dwMask & PFM_TABLE && end_para->member.para.pFmt->wEffects & PFE_TABLE) { - if (this_para == end_para) - { - pRun = c2.pRun; - /* Find the previous tab or end paragraph to use as a delete boundary */ - while (pRun && !(pRun->member.run.nFlags & (MERF_TAB|MERF_ENDPARA))) - pRun = ME_FindItemBack(pRun, diRun); - if (pRun && pRun->member.run.nFlags & MERF_ENDPARA) - { - /* We are in the first cell, and have gone back to the previous - * paragraph, so nothing needs to be protected. */ - pRun = NULL; - } - } else { - /* The deletion starts from before the row, so don't join it with - * previous non-empty paragraphs. */ - pRun = NULL; - if (nOfs > this_para->member.para.nCharOfs) - pRun = ME_FindItemBack(end_para, diRun); - if (!pRun) - pRun = ME_FindItemFwd(end_para, diRun); - } + /* The deletion starts from before the row, so don't join it with + * previous non-empty paragraphs. */ + pRun = NULL; + if (nOfs > this_para->member.para.nCharOfs) + pRun = ME_FindItemBack(end_para, diRun); + if (!pRun) + pRun = ME_FindItemFwd(end_para, diRun); if (pRun) { nCharsToBoundary = ME_GetParagraph(pRun)->member.para.nCharOfs @@ -395,8 +381,8 @@ void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars) } } -static ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, - ME_DisplayItem *table_row) +ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, + ME_DisplayItem *table_row) { WCHAR endl = '\r', tab = '\t'; ME_DisplayItem *run; @@ -404,9 +390,13 @@ static ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, int i; assert(table_row); + assert(table_row->type == diParagraph); if (!editor->bEmulateVersion10) { /* v4.1 */ ME_DisplayItem *insertedCell, *para, *cell; - cell = ME_FindItemFwd(table_row, diCell); + if (table_row->member.para.nFlags & MEPF_ROWEND) + cell = ME_FindItemBack(table_row, diCell); + else + cell = ME_FindItemFwd(table_row, diCell); run = ME_GetTableRowEnd(table_row)->member.para.next_para; run = ME_FindItemFwd(run, diRun); editor->pCursors[0].pRun = run; @@ -416,12 +406,14 @@ static ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, insertedCell = ME_FindItemFwd(para, diCell); /* Copy cell properties */ insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary; + insertedCell->member.cell.border = cell->member.cell.border; while (cell->member.cell.next_cell) { cell = cell->member.cell.next_cell; para = ME_InsertTableCellFromCursor(editor); insertedCell = ME_FindItemBack(para, diCell); /* Copy cell properties */ insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary; + insertedCell->member.cell.border = cell->member.cell.border; }; ME_InsertTableRowEndFromCursor(editor); /* return the table row start for the inserted paragraph */ diff --git a/reactos/dll/win32/riched20/wrap.c b/reactos/dll/win32/riched20/wrap.c index a3c5d544ff6..6f6e32ce1e8 100644 --- a/reactos/dll/win32/riched20/wrap.c +++ b/reactos/dll/win32/riched20/wrap.c @@ -377,7 +377,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) } /* will current run fit? */ - if (wc->pt.x + run->nWidth > wc->context->pt.x + wc->nAvailWidth) + if (wc->pt.x + run->nWidth - wc->context->pt.x > wc->nAvailWidth) { int loc = wc->context->pt.x + wc->nAvailWidth - wc->pt.x; /* total white run ? */