Commit d29f671d authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

richedit: Protect deletion of cell boundaries when not deleting row.

parent bf5ccefc
...@@ -262,13 +262,20 @@ void ME_HideCaret(ME_TextEditor *ed) ...@@ -262,13 +262,20 @@ void ME_HideCaret(ME_TextEditor *ed)
} }
} }
void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
int nChars) BOOL bForce)
{ {
ME_Cursor c; ME_Cursor c;
int shift = 0; int shift = 0;
int totalChars = nChars; int totalChars = nChars;
if (!bForce)
{
ME_ProtectPartialTableDeletion(editor, nOfs, &nChars);
if (nChars == 0)
return FALSE;
}
while(nChars > 0) while(nChars > 0)
{ {
ME_Run *run; ME_Run *run;
...@@ -280,7 +287,7 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, ...@@ -280,7 +287,7 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs,
if (!ME_FindItemFwd(c.pRun, diParagraph)) if (!ME_FindItemFwd(c.pRun, diParagraph))
{ {
return; return TRUE;
} }
keepFirstParaFormat = (totalChars == nChars && nChars <= eollen && keepFirstParaFormat = (totalChars == nChars && nChars <= eollen &&
run->nCharOfs); run->nCharOfs);
...@@ -377,15 +384,16 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, ...@@ -377,15 +384,16 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs,
continue; continue;
} }
} }
return TRUE;
} }
void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
int nChars)
{ {
assert(nCursor>=0 && nCursor<editor->nCursors); assert(nCursor>=0 && nCursor<editor->nCursors);
/* text operations set modified state */ /* text operations set modified state */
editor->nModifyStep = 1; editor->nModifyStep = 1;
ME_InternalDeleteText(editor, ME_GetCursorOfs(editor, nCursor), nChars); return ME_InternalDeleteText(editor, ME_GetCursorOfs(editor, nCursor), nChars,
FALSE);
} }
static ME_DisplayItem * static ME_DisplayItem *
......
...@@ -1082,14 +1082,14 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ...@@ -1082,14 +1082,14 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
if ((format & SFF_SELECTION) && (editor->mode & TM_RICHTEXT)) { if ((format & SFF_SELECTION) && (editor->mode & TM_RICHTEXT)) {
style = ME_GetSelectionInsertStyle(editor); style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to-from); ME_InternalDeleteText(editor, from, to-from, FALSE);
} }
else { else {
ME_DisplayItem *para_item; ME_DisplayItem *para_item;
style = editor->pBuffer->pDefaultStyle; style = editor->pBuffer->pDefaultStyle;
ME_AddRefStyle(style); ME_AddRefStyle(style);
SendMessageA(editor->hWnd, EM_SETSEL, 0, 0); SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor)); ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
from = to = 0; from = to = 0;
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
...@@ -1165,7 +1165,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ...@@ -1165,7 +1165,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_GetTextW(editor, lastchar, newto - linebreakSize, linebreakSize, 0); ME_GetTextW(editor, lastchar, newto - linebreakSize, linebreakSize, 0);
if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) { if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) {
ME_InternalDeleteText(editor, newto - linebreakSize, linebreakSize); ME_InternalDeleteText(editor, newto - linebreakSize, linebreakSize, FALSE);
} }
} }
} }
...@@ -2353,7 +2353,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ...@@ -2353,7 +2353,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (pStruct->flags & ST_SELECTION) { if (pStruct->flags & ST_SELECTION) {
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
style = ME_GetSelectionInsertStyle(editor); style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to - from); ME_InternalDeleteText(editor, from, to - from, FALSE);
if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5)) if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5))
ME_StreamInRTFString(editor, 1, (char *)lParam); ME_StreamInRTFString(editor, 1, (char *)lParam);
else ME_InsertTextFromCursor(editor, 0, wszText, len, style); else ME_InsertTextFromCursor(editor, 0, wszText, len, style);
...@@ -2362,7 +2362,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ...@@ -2362,7 +2362,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
} }
else { else {
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor)); ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5)) if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5))
ME_StreamInRTFString(editor, 0, (char *)lParam); ME_StreamInRTFString(editor, 0, (char *)lParam);
else ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle); else ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle);
...@@ -2530,7 +2530,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ...@@ -2530,7 +2530,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{ {
int from, to; int from, to;
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
ME_InternalDeleteText(editor, from, to-from); ME_InternalDeleteText(editor, from, to-from, FALSE);
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
return 0; return 0;
...@@ -2545,7 +2545,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ...@@ -2545,7 +2545,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
style = ME_GetSelectionInsertStyle(editor); style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to-from); ME_InternalDeleteText(editor, from, to-from, FALSE);
ME_InsertTextFromCursor(editor, 0, wszText, len, style); ME_InsertTextFromCursor(editor, 0, wszText, len, style);
ME_ReleaseStyle(style); ME_ReleaseStyle(style);
/* drop temporary style if line end */ /* drop temporary style if line end */
...@@ -2604,7 +2604,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ...@@ -2604,7 +2604,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
} }
case WM_SETTEXT: case WM_SETTEXT:
{ {
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor)); ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
if (lParam) if (lParam)
{ {
TRACE("WM_SETTEXT lParam==%lx\n",lParam); TRACE("WM_SETTEXT lParam==%lx\n",lParam);
...@@ -2704,7 +2704,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, ...@@ -2704,7 +2704,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
} }
if (SUCCEEDED(hr) && msg == WM_CUT) if (SUCCEEDED(hr) && msg == WM_CUT)
{ {
ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin); ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE);
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
} }
......
...@@ -182,7 +182,7 @@ void ME_MoveCaret(ME_TextEditor *ed); ...@@ -182,7 +182,7 @@ void ME_MoveCaret(ME_TextEditor *ed);
int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact); int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact);
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum); void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum);
void ME_MouseMove(ME_TextEditor *editor, int x, int y); void ME_MouseMove(ME_TextEditor *editor, int x, int y);
void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars); BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style); const WCHAR *str, int len, ME_Style *style);
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor); void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor);
...@@ -198,7 +198,7 @@ BOOL ME_IsSelection(ME_TextEditor *editor); ...@@ -198,7 +198,7 @@ BOOL ME_IsSelection(ME_TextEditor *editor);
void ME_DeleteSelection(ME_TextEditor *editor); void ME_DeleteSelection(ME_TextEditor *editor);
void ME_SendSelChange(ME_TextEditor *editor); void ME_SendSelChange(ME_TextEditor *editor);
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor); void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor);
void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars); BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars, BOOL bForce);
int ME_GetTextLength(ME_TextEditor *editor); int ME_GetTextLength(ME_TextEditor *editor);
int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how); int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how);
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor); ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor);
...@@ -287,6 +287,7 @@ void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor); ...@@ -287,6 +287,7 @@ void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor);
/* table.c */ /* table.c */
BOOL ME_IsInTable(ME_DisplayItem *pItem); BOOL ME_IsInTable(ME_DisplayItem *pItem);
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars);
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow); void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow);
/* undo.c */ /* undo.c */
......
...@@ -47,6 +47,81 @@ BOOL ME_IsInTable(ME_DisplayItem *pItem) ...@@ -47,6 +47,81 @@ BOOL ME_IsInTable(ME_DisplayItem *pItem)
return pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE; return pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE;
} }
/* Table rows should either be deleted completely or not at all. */
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars)
{
ME_Cursor c, c2;
ME_DisplayItem *this_para, *end_para;
ME_DisplayItem *pRun;
int nCharsToBoundary;
ME_CursorFromCharOfs(editor, nOfs, &c);
this_para = ME_GetParagraph(c.pRun);
ME_CursorFromCharOfs(editor, nOfs + *nChars, &c2);
end_para = ME_GetParagraph(c2.pRun);
if (c2.pRun->member.run.nFlags & MERF_ENDPARA) {
/* End offset might be in the middle of the end paragraph run.
* If this is the case, then we need to use the next paragraph as the last
* paragraphs.
*/
int remaining = nOfs + *nChars - c2.pRun->member.run.nCharOfs
- end_para->member.para.nCharOfs;
if (remaining)
{
assert(remaining < c2.pRun->member.run.nCR + c2.pRun->member.run.nLF);
end_para = end_para->member.para.next_para;
}
}
if (this_para->member.para.nCharOfs != nOfs &&
this_para->member.para.pFmt->dwMask & PFM_TABLE &&
this_para->member.para.pFmt->wEffects & PFE_TABLE)
{
pRun = c.pRun;
/* Find the next tab or end paragraph to use as a delete boundary */
while (!(pRun->member.run.nFlags & (MERF_TAB|MERF_ENDPARA)))
pRun = ME_FindItemFwd(pRun, diRun);
nCharsToBoundary = pRun->member.run.nCharOfs
- c.pRun->member.run.nCharOfs
- c.nOffset;
*nChars = min(*nChars, nCharsToBoundary);
} 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);
}
if (pRun)
{
nCharsToBoundary = ME_GetParagraph(pRun)->member.para.nCharOfs
+ pRun->member.run.nCharOfs
- nOfs;
if (nCharsToBoundary >= 0)
*nChars = min(*nChars, nCharsToBoundary);
}
}
if (*nChars < 0)
nChars = 0;
}
static ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, static ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor,
ME_DisplayItem *table_row) ME_DisplayItem *table_row)
{ {
......
...@@ -300,7 +300,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem) ...@@ -300,7 +300,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
} }
case diUndoDeleteRun: case diUndoDeleteRun:
{ {
ME_InternalDeleteText(editor, pUItem->nStart, pUItem->nLen); ME_InternalDeleteText(editor, pUItem->nStart, pUItem->nLen, TRUE);
break; break;
} }
case diUndoJoinParagraphs: case diUndoJoinParagraphs:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment