Commit 2da0d8e9 authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

richedit: Use ME_Cursor instead of offsets for ME_SetCharFormat.

The test that succeeded from this change was as a result of allowing the end of the character format change be specified using NULL as the rest of the text. Before, the end paragraph run at the end of the text was not being set for this case, when all the text was supposed to have its character format changed.
parent ade37203
......@@ -3319,7 +3319,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
if (editor->mode & TM_PLAINTEXT)
ME_SetDefaultCharFormat(editor, p);
else {
ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p);
ME_Cursor start;
ME_SetCursorToStart(editor, &start);
ME_SetCharFormat(editor, &start, NULL, p);
editor->nModifyStep = 1;
}
} else if (editor->mode & TM_PLAINTEXT) {
......@@ -3449,6 +3451,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
CHARFORMAT2W fmt;
HDC hDC;
BOOL bRepaint = LOWORD(lParam);
ME_Cursor start;
if (!wParam)
wParam = (WPARAM)GetStockObject(SYSTEM_FONT);
......@@ -3456,7 +3459,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
hDC = ITextHost_TxGetDC(editor->texthost);
ME_CharFormatFromLogFont(hDC, &lf, &fmt);
ITextHost_TxReleaseDC(editor->texthost, hDC);
ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), &fmt);
ME_SetCursorToStart(editor, &start);
ME_SetCharFormat(editor, &start, NULL, &fmt);
ME_SetDefaultCharFormat(editor, &fmt);
ME_CommitUndo(editor);
......@@ -4859,7 +4863,7 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_m
link.cbSize = sizeof(link);
link.dwMask = CFM_LINK;
link.dwEffects = 0;
ME_SetCharFormat(editor, beforeURL[0], beforeURL[1] - beforeURL[0], &link);
ME_SetCharFormat(editor, &from, &to, &link);
modified = TRUE;
}
}
......@@ -4878,7 +4882,7 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_m
link.cbSize = sizeof(link);
link.dwMask = CFM_LINK;
link.dwEffects = CFE_LINK;
ME_SetCharFormat(editor, inURL[0], inURL[1] - inURL[0], &link);
ME_SetCharFormat(editor, &from, &to, &link);
modified = TRUE;
}
}
......
......@@ -147,7 +147,7 @@ void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCurso
void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppPara, ME_DisplayItem **ppRun, int *pOfs);
int ME_CharOfsFromRunOfs(ME_TextEditor *editor, const ME_DisplayItem *pPara, const ME_DisplayItem *pRun, int nOfs);
void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift);
void ME_SetCharFormat(ME_TextEditor *editor, int nFrom, int nLen, CHARFORMAT2W *pFmt);
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt);
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt);
void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from,
const ME_Cursor *to, CHARFORMAT2W *pFmt);
......
......@@ -335,6 +335,8 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
int i, shift;
ME_UndoItem *undo = NULL;
int end_len;
CHARFORMAT2W fmt;
ME_Cursor startCur, endCur;
assert(tp->type == diParagraph);
assert(tp->member.para.next_para);
......@@ -351,12 +353,15 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
end_len = pRun->member.run.strText->nLen;
{
/* null char format operation to store the original char format for the ENDPARA run */
CHARFORMAT2W fmt;
ME_InitCharFormat2W(&fmt);
ME_SetCharFormat(editor, pNext->member.para.nCharOfs - end_len, end_len, &fmt);
}
/* null char format operation to store the original char format for the ENDPARA run */
ME_InitCharFormat2W(&fmt);
endCur.pPara = pNext;
endCur.pRun = ME_FindItemFwd(pNext, diRun);
endCur.nOffset = 0;
startCur = endCur;
ME_PrevRun(&startCur.pPara, &startCur.pRun);
ME_SetCharFormat(editor, &startCur, &endCur, &fmt);
undo = ME_AddUndoItem(editor, diUndoSplitParagraph, pNext);
if (undo)
{
......
......@@ -726,15 +726,13 @@ void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Ru
/******************************************************************************
* ME_SetSelectionCharFormat
*
*
* Applies a style change, either to a current selection, or to insert cursor
* (ie. the style next typed characters will use).
*/
*/
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelectionOfs(editor, &nFrom, &nTo);
if (nFrom == nTo)
if (!ME_IsSelection(editor))
{
ME_Style *s;
if (!editor->pBuffer->pCharStyle)
......@@ -742,57 +740,83 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
s = ME_ApplyStyle(editor->pBuffer->pCharStyle, pFmt);
ME_ReleaseStyle(editor->pBuffer->pCharStyle);
editor->pBuffer->pCharStyle = s;
} else {
ME_Cursor *from, *to;
ME_GetSelection(editor, &from, &to);
ME_SetCharFormat(editor, from, to, pFmt);
}
else
ME_SetCharFormat(editor, nFrom, nTo-nFrom, pFmt);
}
/******************************************************************************
* ME_SetCharFormat
*
*
* Applies a style change to the specified part of the text
*/
void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W *pFmt)
*
* The start and end cursors specify the part of the text. These cursors will
* be updated to stay valid, but this function may invalidate other
* non-selection cursors. The end cursor may be NULL to specify all the text
* following the start cursor.
*
* If no text is selected, then nothing is done.
*/
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt)
{
ME_Cursor tmp, tmp2;
ME_DisplayItem *para;
ME_DisplayItem *run;
ME_DisplayItem *end_run = NULL;
ME_CursorFromCharOfs(editor, nOfs, &tmp);
if (tmp.nOffset)
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
if (end && start->pRun == end->pRun && start->nOffset == end->nOffset)
return;
ME_CursorFromCharOfs(editor, nOfs+nChars, &tmp2);
if (tmp2.nOffset)
tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset);
if (start->nOffset)
{
/* SplitRunSimple may or may not update the cursors, depending on whether they
* are selection cursors, but we need to make sure they are valid. */
ME_DisplayItem *split_run = start->pRun;
int split_offset = start->nOffset;
start->pRun = ME_SplitRunSimple(editor, split_run, split_offset);
start->nOffset = 0;
if (end && end->pRun == split_run)
{
end->pRun = start->pRun;
end->nOffset -= split_offset;
}
}
if (end && end->nOffset)
{
end_run = end->pRun = ME_SplitRunSimple(editor, end->pRun, end->nOffset);
end->nOffset = 0;
}
para = tmp.pPara;
run = start->pRun;
para = start->pPara;
para->member.para.nFlags |= MEPF_REWRAP;
while(tmp.pRun != tmp2.pRun)
while(run != end_run)
{
ME_UndoItem *undo = NULL;
ME_Style *new_style = ME_ApplyStyle(tmp.pRun->member.run.style, pFmt);
ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt);
/* ME_DumpStyle(new_style); */
undo = ME_AddUndoItem(editor, diUndoSetCharFormat, NULL);
if (undo) {
undo->nStart = tmp.pRun->member.run.nCharOfs+para->member.para.nCharOfs;
undo->nLen = tmp.pRun->member.run.strText->nLen;
undo->di.member.ustyle = tmp.pRun->member.run.style;
undo->nStart = run->member.run.nCharOfs+para->member.para.nCharOfs;
undo->nLen = run->member.run.strText->nLen;
undo->di.member.ustyle = run->member.run.style;
/* we'd have to addref undo...ustyle and release tmp...style
but they'd cancel each other out so we can do nothing instead */
}
else
ME_ReleaseStyle(tmp.pRun->member.run.style);
tmp.pRun->member.run.style = new_style;
tmp.pRun = ME_FindItemFwd(tmp.pRun, diRunOrParagraph);
if (tmp.pRun->type == diParagraph)
ME_ReleaseStyle(run->member.run.style);
run->member.run.style = new_style;
run = ME_FindItemFwd(run, diRunOrParagraph);
if (run && run->type == diParagraph)
{
para = tmp.pRun;
tmp.pRun = ME_FindItemFwd(tmp.pRun, diRun);
if (tmp.pRun != tmp2.pRun)
para = run;
run = ME_FindItemFwd(run, diRun);
if (run != end_run)
para->member.para.nFlags |= MEPF_REWRAP;
}
assert(tmp.pRun);
}
}
......
......@@ -743,7 +743,7 @@ static void test_EM_SETCHARFORMAT(void)
(LPARAM) &cf2);
ok(rc == 1, "EM_SETCHARFORMAT returned %d instead of 1\n", rc);
rc = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
todo_wine ok(rc == TRUE, "Should not be able to undo here.\n");
ok(rc == TRUE, "Should not be able to undo here.\n");
SendMessage(hwndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0);
cf2.cbSize = sizeof(CHARFORMAT2);
......
......@@ -298,7 +298,10 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
}
case diUndoSetCharFormat:
{
ME_SetCharFormat(editor, pUItem->nStart, pUItem->nLen, &pItem->member.ustyle->fmt);
ME_Cursor start, end;
ME_CursorFromCharOfs(editor, pUItem->nStart, &start);
ME_CursorFromCharOfs(editor, pUItem->nStart + pUItem->nLen, &end);
ME_SetCharFormat(editor, &start, &end, &pItem->member.ustyle->fmt);
break;
}
case diUndoInsertRun:
......
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