- Sync riched20 with Wine 1.1.19

- Fixes a problem where the richedit control forwarded messages to itself through user32, also known as the Winrar installation stack overflow, bug #4197

svn path=/trunk/; revision=40545
This commit is contained in:
Gregor Schneider 2009-04-16 17:49:22 +00:00
parent 92a3744982
commit 5e9875c679
20 changed files with 711 additions and 885 deletions

View file

@ -42,7 +42,9 @@ void ME_GetSelection(ME_TextEditor *editor, int *from, int *to)
int ME_GetTextLength(ME_TextEditor *editor) int ME_GetTextLength(ME_TextEditor *editor)
{ {
return ME_CharOfsFromRunOfs(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun), 0); ME_DisplayItem *pLast = editor->pBuffer->pLast;
return ME_CharOfsFromRunOfs(editor, pLast->member.para.prev_para,
ME_FindItemBack(pLast, diRun), 0);
} }
@ -93,9 +95,11 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
/* select all */ /* select all */
if (from == 0 && to == -1) if (from == 0 && to == -1)
{ {
editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun); editor->pCursors[1].pPara = editor->pBuffer->pFirst->member.para.next_para;
editor->pCursors[1].nOffset = 0; editor->pCursors[1].pRun = ME_FindItemFwd(editor->pCursors[1].pPara, diRun);
editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); editor->pCursors[1].nOffset = 0;
editor->pCursors[0].pPara = editor->pBuffer->pLast->member.para.prev_para;
editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
ME_InvalidateSelection(editor); ME_InvalidateSelection(editor);
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
@ -144,8 +148,10 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
if (selectionEnd) if (selectionEnd)
{ {
editor->pCursors[1].pRun = editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); editor->pCursors[0].pPara = editor->pBuffer->pLast->member.para.prev_para;
editor->pCursors[1].nOffset = editor->pCursors[0].nOffset = 0; editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
ME_InvalidateSelection(editor); ME_InvalidateSelection(editor);
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
return len; return len;
@ -166,69 +172,58 @@ void
ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
int *x, int *y, int *height) int *x, int *y, int *height)
{ {
ME_DisplayItem *pCursorRun = pCursor->pRun; ME_DisplayItem *row;
ME_DisplayItem *pSizeRun = pCursor->pRun; ME_DisplayItem *run = pCursor->pRun;
ME_DisplayItem *para = pCursor->pPara;
ME_DisplayItem *pSizeRun = run;
ME_Context c;
SIZE sz = {0, 0};
assert(height && x && y); assert(height && x && y);
assert(!(ME_GetParagraph(pCursorRun)->member.para.nFlags & MEPF_REWRAP)); assert(~para->member.para.nFlags & MEPF_REWRAP);
assert(pCursor->pRun); assert(run && run->type == diRun);
assert(pCursor->pRun->type == diRun); assert(para && para->type == diParagraph);
if (pCursorRun->type == diRun) { row = ME_FindItemBack(run, diStartRowOrParagraph);
ME_DisplayItem *row = ME_FindItemBack(pCursorRun, diStartRowOrParagraph); assert(row && row->type == diStartRow);
if (row) { ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
HDC hDC = ITextHost_TxGetDC(editor->texthost);
ME_Context c;
ME_DisplayItem *run = pCursorRun;
ME_DisplayItem *para = NULL;
SIZE sz = {0, 0};
ME_InitContext(&c, editor, hDC); if (!pCursor->nOffset)
{
if (!pCursor->nOffset) ME_DisplayItem *prev = ME_FindItemBack(run, diRunOrParagraph);
{ assert(prev);
ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrParagraph); if (prev->type == diRun)
assert(prev); pSizeRun = prev;
if (prev->type == diRun) }
pSizeRun = prev; if (editor->bCaretAtEnd && !pCursor->nOffset &&
} run == ME_FindItemFwd(row, diRun))
assert(row->type == diStartRow); /* paragraph -> run without start row ?*/ {
para = ME_FindItemBack(row, diParagraph); ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph);
assert(para); assert(tmp);
assert(para->type == diParagraph); if (tmp->type == diRun)
if (editor->bCaretAtEnd && !pCursor->nOffset && {
run == ME_FindItemFwd(row, diRun)) row = ME_FindItemBack(tmp, diStartRow);
{ pSizeRun = run = tmp;
ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph); assert(run);
assert(tmp); assert(run->type == diRun);
if (tmp->type == diRun) sz = ME_GetRunSize(&c, &para->member.para,
{ &run->member.run, run->member.run.strText->nLen,
row = ME_FindItemBack(tmp, diStartRow); row->member.row.nLMargin);
pSizeRun = run = tmp;
assert(run);
assert(run->type == diRun);
sz = ME_GetRunSize(&c, &para->member.para,
&run->member.run, ME_StrLen(run->member.run.strText),
row->member.row.nLMargin);
}
}
if (pCursor->nOffset) {
sz = ME_GetRunSize(&c, &para->member.para, &run->member.run, pCursor->nOffset,
row->member.row.nLMargin);
}
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
*x = c.rcView.left + run->member.run.pt.x + sz.cx - editor->horz_si.nPos;
*y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
+ run->member.run.pt.y - pSizeRun->member.run.nAscent - editor->vert_si.nPos;
ME_DestroyContext(&c);
return;
} }
} }
*height = 10; /* FIXME use global font */ if (pCursor->nOffset) {
*x = 0; sz = ME_GetRunSize(&c, &para->member.para, &run->member.run,
*y = 0; pCursor->nOffset, row->member.row.nLMargin);
}
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
*x = c.rcView.left + run->member.run.pt.x + sz.cx - editor->horz_si.nPos;
*y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
+ run->member.run.pt.y - pSizeRun->member.run.nAscent
- editor->vert_si.nPos;
ME_DestroyContext(&c);
return;
} }
@ -237,8 +232,6 @@ ME_MoveCaret(ME_TextEditor *editor)
{ {
int x, y, height; int x, y, height;
if (ME_WrapMarkedParagraphs(editor))
ME_UpdateScrollBar(editor);
ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height);
if(editor->bHaveFocus && !ME_IsSelection(editor)) if(editor->bHaveFocus && !ME_IsSelection(editor))
{ {
@ -273,17 +266,11 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
int totalChars = nChars; int totalChars = nChars;
ME_DisplayItem *start_para; ME_DisplayItem *start_para;
{ /* Prevent deletion past last end of paragraph run. */
/* Prevent deletion past last end of paragraph run. */ nChars = min(nChars, ME_GetTextLength(editor) - nOfs);
ME_DisplayItem *pTextEnd = editor->pBuffer->pLast;
int nMaxChars = pTextEnd->member.para.prev_para->member.para.nCharOfs;
nMaxChars += ME_FindItemBack(pTextEnd, diRun)->member.run.nCharOfs;
nMaxChars -= nOfs;
nChars = min(nChars, nMaxChars);
}
ME_CursorFromCharOfs(editor, nOfs, &c); ME_CursorFromCharOfs(editor, nOfs, &c);
start_para = ME_GetParagraph(c.pRun); start_para = c.pPara;
if (!bForce) if (!bForce)
{ {
@ -298,11 +285,12 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
ME_CursorFromCharOfs(editor, nOfs+nChars, &c); ME_CursorFromCharOfs(editor, nOfs+nChars, &c);
if (!c.nOffset && if (!c.nOffset &&
nOfs+nChars == (c.pRun->member.run.nCharOfs nOfs+nChars == (c.pRun->member.run.nCharOfs
+ ME_GetParagraph(c.pRun)->member.para.nCharOfs)) + c.pPara->member.para.nCharOfs))
{ {
/* We aren't deleting anything in this run, so we will go back to the /* We aren't deleting anything in this run, so we will go back to the
* last run we are deleting text in. */ * last run we are deleting text in. */
c.pRun = ME_FindItemBack(c.pRun, diRun); c.pRun = ME_FindItemBack(c.pRun, diRun);
c.pPara = ME_GetParagraph(c.pRun);
c.nOffset = c.pRun->member.run.strText->nLen; c.nOffset = c.pRun->member.run.strText->nLen;
} }
run = &c.pRun->member.run; run = &c.pRun->member.run;
@ -338,7 +326,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
keepFirstParaFormat = TRUE; keepFirstParaFormat = TRUE;
} }
} }
ME_JoinParagraphs(editor, ME_GetParagraph(c.pRun), keepFirstParaFormat); ME_JoinParagraphs(editor, c.pPara, keepFirstParaFormat);
/* ME_SkipAndPropagateCharOffset(p->pRun, shift); */ /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
ME_CheckCharOffsets(editor); ME_CheckCharOffsets(editor);
nChars -= (eollen < nChars) ? eollen : nChars; nChars -= (eollen < nChars) ? eollen : nChars;
@ -364,7 +352,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
nCharsToDelete, nChars, c.nOffset, nCharsToDelete, nChars, c.nOffset,
debugstr_w(run->strText->szData), run->strText->nLen); debugstr_w(run->strText->szData), run->strText->nLen);
if (!c.nOffset && ME_StrVLen(run->strText) == nCharsToDelete) if (!c.nOffset && run->strText->nLen == nCharsToDelete)
{ {
/* undo = reinsert whole run */ /* undo = reinsert whole run */
/* nOfs is a character offset (from the start of the document /* nOfs is a character offset (from the start of the document
@ -386,10 +374,10 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
TRACE("Post deletion string: %s (%d)\n", debugstr_w(run->strText->szData), run->strText->nLen); TRACE("Post deletion string: %s (%d)\n", debugstr_w(run->strText->szData), run->strText->nLen);
TRACE("Shift value: %d\n", shift); TRACE("Shift value: %d\n", shift);
ME_StrDeleteV(run->strText, c.nOffset, nCharsToDelete); ME_StrDeleteV(run->strText, c.nOffset, nCharsToDelete);
/* update cursors (including c) */ /* update cursors (including c) */
for (i=-1; i<editor->nCursors; i++) { for (i=-1; i<editor->nCursors; i++) {
ME_Cursor *pThisCur = editor->pCursors + i; ME_Cursor *pThisCur = editor->pCursors + i;
if (i == -1) pThisCur = &c; if (i == -1) pThisCur = &c;
if (pThisCur->pRun == cursor.pRun) { if (pThisCur->pRun == cursor.pRun) {
if (pThisCur->nOffset > cursor.nOffset) { if (pThisCur->nOffset > cursor.nOffset) {
@ -398,9 +386,9 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
else else
pThisCur->nOffset -= nCharsToDelete; pThisCur->nOffset -= nCharsToDelete;
assert(pThisCur->nOffset >= 0); assert(pThisCur->nOffset >= 0);
assert(pThisCur->nOffset <= ME_StrVLen(run->strText)); assert(pThisCur->nOffset <= run->strText->nLen);
} }
if (pThisCur->nOffset == ME_StrVLen(run->strText)) if (pThisCur->nOffset == run->strText->nLen)
{ {
pThisCur->pRun = ME_FindItemFwd(pThisCur->pRun, diRunOrParagraphOrEnd); pThisCur->pRun = ME_FindItemFwd(pThisCur->pRun, diRunOrParagraphOrEnd);
assert(pThisCur->pRun->type == diRun); assert(pThisCur->pRun->type == diRun);
@ -408,21 +396,21 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
} }
} }
} }
/* c = updated data now */ /* c = updated data now */
if (c.pRun == cursor.pRun) if (c.pRun == cursor.pRun)
ME_SkipAndPropagateCharOffset(c.pRun, shift); ME_SkipAndPropagateCharOffset(c.pRun, shift);
else else
ME_PropagateCharOffset(c.pRun, shift); ME_PropagateCharOffset(c.pRun, shift);
if (!ME_StrVLen(cursor.pRun->member.run.strText)) if (!cursor.pRun->member.run.strText->nLen)
{ {
TRACE("Removing useless run\n"); TRACE("Removing useless run\n");
ME_Remove(cursor.pRun); ME_Remove(cursor.pRun);
ME_DestroyDisplayItem(cursor.pRun); ME_DestroyDisplayItem(cursor.pRun);
} }
shift = 0; shift = 0;
/* /*
ME_CheckCharOffsets(editor); ME_CheckCharOffsets(editor);
@ -577,6 +565,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
/* ME_SplitParagraph increases style refcount */ /* ME_SplitParagraph increases style refcount */
tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, eol_str, 0); tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, eol_str, 0);
p->pRun = ME_FindItemFwd(tp, diRun); p->pRun = ME_FindItemFwd(tp, diRun);
p->pPara = ME_GetParagraph(p->pRun);
end_run = ME_FindItemBack(tp, diRun); end_run = ME_FindItemBack(tp, diRun);
ME_ReleaseStyle(end_run->member.run.style); ME_ReleaseStyle(end_run->member.run.style);
end_run->member.run.style = tmp_style; end_run->member.run.style = tmp_style;
@ -593,11 +582,12 @@ static BOOL
ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs) ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
{ {
ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pRun = pCursor->pRun;
if (nRelOfs == -1) if (nRelOfs == -1)
{ {
if (!pCursor->nOffset) if (!pCursor->nOffset)
{ {
ME_DisplayItem *pPara = pCursor->pPara;
do { do {
pRun = ME_FindItemBack(pRun, diRunOrParagraph); pRun = ME_FindItemBack(pRun, diRunOrParagraph);
assert(pRun); assert(pRun);
@ -606,9 +596,11 @@ ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
case diRun: case diRun:
break; break;
case diParagraph: case diParagraph:
if (pRun->member.para.prev_para->type == diTextStart) pPara = pRun;
if (pPara->member.para.prev_para->type == diTextStart)
return FALSE; return FALSE;
pRun = ME_FindItemBack(pRun, diRunOrParagraph); pRun = ME_FindItemBack(pPara, diRunOrParagraph);
pPara = pPara->member.para.prev_para;
/* every paragraph ought to have at least one run */ /* every paragraph ought to have at least one run */
assert(pRun && pRun->type == diRun); assert(pRun && pRun->type == diRun);
assert(pRun->member.run.nFlags & MERF_ENDPARA); assert(pRun->member.run.nFlags & MERF_ENDPARA);
@ -619,23 +611,24 @@ ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
} }
} while (RUN_IS_HIDDEN(&pRun->member.run) || } while (RUN_IS_HIDDEN(&pRun->member.run) ||
pRun->member.run.nFlags & MERF_HIDDEN); pRun->member.run.nFlags & MERF_HIDDEN);
pCursor->pPara = pPara;
pCursor->pRun = pRun; pCursor->pRun = pRun;
if (pRun->member.run.nFlags & MERF_ENDPARA) if (pRun->member.run.nFlags & MERF_ENDPARA)
pCursor->nOffset = 0; pCursor->nOffset = 0;
else else
pCursor->nOffset = pRun->member.run.strText->nLen; pCursor->nOffset = pRun->member.run.strText->nLen;
} }
if (pCursor->nOffset) if (pCursor->nOffset)
pCursor->nOffset = ME_StrRelPos2(pCursor->pRun->member.run.strText, pCursor->nOffset, nRelOfs); pCursor->nOffset = pCursor->nOffset + nRelOfs;
return TRUE; return TRUE;
} }
else else
{ {
if (!(pRun->member.run.nFlags & MERF_ENDPARA)) if (!(pRun->member.run.nFlags & MERF_ENDPARA))
{ {
int new_ofs = ME_StrRelPos2(pRun->member.run.strText, pCursor->nOffset, nRelOfs); int new_ofs = pCursor->nOffset + nRelOfs;
if (new_ofs < pRun->member.run.strText->nLen) if (new_ofs < pRun->member.run.strText->nLen)
{ {
pCursor->nOffset = new_ofs; pCursor->nOffset = new_ofs;
@ -648,6 +641,7 @@ ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
pRun->member.run.nFlags & MERF_HIDDEN)); pRun->member.run.nFlags & MERF_HIDDEN));
if (pRun) if (pRun)
{ {
pCursor->pPara = ME_GetParagraph(pRun);
pCursor->pRun = pRun; pCursor->pRun = pRun;
pCursor->nOffset = 0; pCursor->nOffset = 0;
return TRUE; return TRUE;
@ -670,7 +664,7 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{ {
nOffset = ME_CallWordBreakProc(editor, pRun->member.run.strText, nOffset = ME_CallWordBreakProc(editor, pRun->member.run.strText,
nOffset, WB_MOVEWORDLEFT); nOffset, WB_MOVEWORDLEFT);
if (nOffset) if (nOffset)
break; break;
pOtherRun = ME_FindItemBack(pRun, diRunOrParagraph); pOtherRun = ME_FindItemBack(pRun, diRunOrParagraph);
if (pOtherRun->type == diRun) if (pOtherRun->type == diRun)
@ -697,7 +691,7 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
if (pOtherRun->member.para.prev_para->type == diTextStart) if (pOtherRun->member.para.prev_para->type == diTextStart)
return FALSE; return FALSE;
pRun = ME_FindItemBack(pOtherRun, diRunOrParagraph); pRun = ME_FindItemBack(pOtherRun, diRun);
} }
break; break;
} }
@ -743,6 +737,7 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
} }
} }
} }
cursor->pPara = ME_GetParagraph(pRun);
cursor->pRun = pRun; cursor->pRun = pRun;
cursor->nOffset = nOffset; cursor->nOffset = nOffset;
return TRUE; return TRUE;
@ -786,18 +781,22 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun);
else else
editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun);
editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
pItem = ME_FindItemBack(pItem, backSearchType); pItem = ME_FindItemBack(pItem, backSearchType);
editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun);
editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun);
editor->pCursors[1].nOffset = 0; editor->pCursors[1].nOffset = 0;
break; break;
} }
case stDocument: case stDocument:
/* Select everything with cursor anchored from the start of the text */ /* Select everything with cursor anchored from the start of the text */
editor->nSelectionType = stDocument; editor->nSelectionType = stDocument;
editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun); editor->pCursors[1].pPara = editor->pBuffer->pFirst->member.para.next_para;
editor->pCursors[1].pRun = ME_FindItemFwd(editor->pCursors[1].pPara, diRun);
editor->pCursors[1].nOffset = 0; editor->pCursors[1].nOffset = 0;
editor->pCursors[0].pPara = editor->pBuffer->pLast->member.para.prev_para;
editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
break; break;
@ -811,8 +810,8 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor) int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
{ {
ME_Cursor *pCursor = &editor->pCursors[nCursor]; ME_Cursor *pCursor = &editor->pCursors[nCursor];
return ME_GetParagraph(pCursor->pRun)->member.para.nCharOfs return pCursor->pPara->member.para.nCharOfs
+ pCursor->pRun->member.run.nCharOfs + pCursor->nOffset; + pCursor->pRun->member.run.nCharOfs + pCursor->nOffset;
} }
/* Helper function for ME_FindPixelPos to find paragraph within tables */ /* Helper function for ME_FindPixelPos to find paragraph within tables */
@ -868,6 +867,7 @@ static BOOL ME_ReturnFoundPos(ME_TextEditor *editor, ME_DisplayItem *found,
result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun); result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
result->nOffset = 0; result->nOffset = 0;
} }
result->pPara = ME_GetParagraph(result->pRun);
return isExact; return isExact;
} }
@ -968,6 +968,7 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y,
last = p; last = p;
} }
result->pRun = ME_FindItemBack(p, diRun); result->pRun = ME_FindItemBack(p, diRun);
result->pPara = ME_GetParagraph(result->pRun);
result->nOffset = 0; result->nOffset = 0;
assert(result->pRun->member.run.nFlags & MERF_ENDPARA); assert(result->pRun->member.run.nFlags & MERF_ENDPARA);
return FALSE; return FALSE;
@ -996,8 +997,8 @@ int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact)
y += editor->vert_si.nPos; y += editor->vert_si.nPos;
bResult = ME_FindPixelPos(editor, x, y, &cursor, NULL); bResult = ME_FindPixelPos(editor, x, y, &cursor, NULL);
if (isExact) *isExact = bResult; if (isExact) *isExact = bResult;
return (ME_GetParagraph(cursor.pRun)->member.para.nCharOfs return cursor.pPara->member.para.nCharOfs
+ cursor.pRun->member.run.nCharOfs + cursor.nOffset); + cursor.pRun->member.run.nCharOfs + cursor.nOffset;
} }
@ -1038,6 +1039,7 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
diStartRowOrParagraph:diParagraph); diStartRowOrParagraph:diParagraph);
pItem = ME_FindItemBack(editor->pCursors[1].pRun, searchType); pItem = ME_FindItemBack(editor->pCursors[1].pRun, searchType);
editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun);
editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun);
editor->pCursors[1].nOffset = 0; editor->pCursors[1].nOffset = 0;
} }
} }
@ -1057,6 +1059,7 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun);
else else
editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun);
editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
} }
} }
@ -1272,8 +1275,6 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
pItem = ME_FindItemFwd(pRun, diStartRow); pItem = ME_FindItemFwd(pRun, diStartRow);
if (!pItem) if (!pItem)
return; /* row not found - ignore */ return; /* row not found - ignore */
/* FIXME If diParagraph is before diStartRow, wrap the next paragraph?
*/
pNewPara = ME_GetParagraph(pItem); pNewPara = ME_GetParagraph(pItem);
if (pOldPara->member.para.nFlags & MEPF_ROWSTART || if (pOldPara->member.para.nFlags & MEPF_ROWSTART ||
(pOldPara->member.para.pCell && (pOldPara->member.para.pCell &&
@ -1301,6 +1302,7 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
return; return;
} }
pCursor->pRun = ME_FindRunInRow(editor, pItem, x, &pCursor->nOffset, &editor->bCaretAtEnd); pCursor->pRun = ME_FindRunInRow(editor, pItem, x, &pCursor->nOffset, &editor->bCaretAtEnd);
pCursor->pPara = ME_GetParagraph(pCursor->pRun);
assert(pCursor->pRun); assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
} }
@ -1311,7 +1313,8 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
if (editor->vert_si.nPos < p->member.row.nHeight) if (editor->vert_si.nPos < p->member.row.nHeight)
{ {
pCursor->pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun); pCursor->pPara = editor->pBuffer->pFirst->member.para.next_para;
pCursor->pRun = ME_FindItemFwd(pCursor->pPara, diRun);
pCursor->nOffset = 0; pCursor->nOffset = 0;
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
/* Native clears seems to clear this x value on page up at the top /* Native clears seems to clear this x value on page up at the top
@ -1357,6 +1360,7 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset, pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset,
&editor->bCaretAtEnd); &editor->bCaretAtEnd);
pCursor->pPara = ME_GetParagraph(pCursor->pRun);
} }
assert(pCursor->pRun); assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
@ -1376,6 +1380,7 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
if (editor->vert_si.nPos >= y - editor->sizeWindow.cy) if (editor->vert_si.nPos >= y - editor->sizeWindow.cy)
{ {
pCursor->pPara = editor->pBuffer->pLast->member.para.prev_para;
pCursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); pCursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
pCursor->nOffset = 0; pCursor->nOffset = 0;
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
@ -1418,6 +1423,7 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset, pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset,
&editor->bCaretAtEnd); &editor->bCaretAtEnd);
pCursor->pPara = ME_GetParagraph(pCursor->pRun);
} }
assert(pCursor->pRun); assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
@ -1426,7 +1432,6 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
ME_WrapMarkedParagraphs(editor);
if (pRow) { if (pRow) {
ME_DisplayItem *pRun; ME_DisplayItem *pRun;
if (editor->bCaretAtEnd && !pCursor->nOffset) { if (editor->bCaretAtEnd && !pCursor->nOffset) {
@ -1437,6 +1442,7 @@ static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
pRun = ME_FindItemFwd(pRow, diRun); pRun = ME_FindItemFwd(pRow, diRun);
if (pRun) { if (pRun) {
pCursor->pRun = pRun; pCursor->pRun = pRun;
assert(pCursor->pPara == ME_GetParagraph(pRun));
pCursor->nOffset = 0; pCursor->nOffset = 0;
} }
} }
@ -1445,48 +1451,42 @@ static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diTextStart); pCursor->pPara = editor->pBuffer->pFirst->member.para.next_para;
if (pRow) { pCursor->pRun = ME_FindItemFwd(pCursor->pPara, diRun);
ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun); pCursor->nOffset = 0;
if (pRun) { editor->bCaretAtEnd = FALSE;
pCursor->pRun = pRun;
pCursor->nOffset = 0;
}
}
} }
static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRow; ME_DisplayItem *pRow;
if (editor->bCaretAtEnd && !pCursor->nOffset) if (editor->bCaretAtEnd && !pCursor->nOffset)
return; return;
pRow = ME_FindItemFwd(pCursor->pRun, diStartRowOrParagraphOrEnd); pRow = ME_FindItemFwd(pCursor->pRun, diStartRowOrParagraphOrEnd);
assert(pRow); assert(pRow);
if (pRow->type == diStartRow) { if (pRow->type == diStartRow) {
/* FIXME WTF was I thinking about here ? */
ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun); ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun);
assert(pRun); assert(pRun);
pCursor->pRun = pRun; pCursor->pRun = pRun;
assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun));
pCursor->nOffset = 0; pCursor->nOffset = 0;
editor->bCaretAtEnd = 1; editor->bCaretAtEnd = TRUE;
return; return;
} }
pCursor->pRun = ME_FindItemBack(pRow, diRun); pCursor->pRun = ME_FindItemBack(pRow, diRun);
assert(pCursor->pRun && pCursor->pRun->member.run.nFlags & MERF_ENDPARA); assert(pCursor->pRun && pCursor->pRun->member.run.nFlags & MERF_ENDPARA);
assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun));
pCursor->nOffset = 0; pCursor->nOffset = 0;
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
} }
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *p = ME_FindItemFwd(pCursor->pRun, diTextEnd); pCursor->pPara = editor->pBuffer->pLast->member.para.prev_para;
assert(p); pCursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
p = ME_FindItemBack(p, diRun); assert(pCursor->pRun->member.run.nFlags & MERF_ENDPARA);
assert(p);
assert(p->member.run.nFlags & MERF_ENDPARA);
pCursor->pRun = p;
pCursor->nOffset = 0; pCursor->nOffset = 0;
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
} }

View file

@ -22,7 +22,7 @@
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC) void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
{ {
c->nSequence = editor->nSequence++; c->nSequence = editor->nSequence++;
c->hDC = hDC; c->hDC = hDC;
c->editor = editor; c->editor = editor;
c->pt.x = 0; c->pt.x = 0;
@ -35,6 +35,10 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
} else { } else {
c->dpi.cx = c->dpi.cy = 96; c->dpi.cx = c->dpi.cy = 96;
} }
if (editor->nAvailWidth)
c->nAvailWidth = ME_twips2pointsX(c, editor->nAvailWidth);
else
c->nAvailWidth = c->rcView.right - c->rcView.left;
} }
void ME_DestroyContext(ME_Context *c) void ME_DestroyContext(ME_Context *c)

View file

@ -69,7 +69,7 @@
! - EM_GETTHUMB ! - EM_GETTHUMB
+ EM_GETTEXTEX 2.0 + EM_GETTEXTEX 2.0
+ EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented) + EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented)
- EM_GETTEXTMODE 2.0 + EM_GETTEXTMODE 2.0
? + EM_GETTEXTRANGE (ANSI&Unicode) ? + EM_GETTEXTRANGE (ANSI&Unicode)
- EM_GETTYPOGRAPHYOPTIONS 3.0 - EM_GETTYPOGRAPHYOPTIONS 3.0
- EM_GETUNDONAME - EM_GETUNDONAME
@ -507,7 +507,7 @@ void ME_RTFParAttrHook(RTF_Info *info)
/* We are just after a table row. */ /* We are just after a table row. */
RTFFlushOutputBuffer(info); RTFFlushOutputBuffer(info);
cursor = info->editor->pCursors[0]; cursor = info->editor->pCursors[0];
para = ME_GetParagraph(cursor.pRun); para = cursor.pPara;
if (para == info->tableDef->tableRowStart->member.para.next_para if (para == info->tableDef->tableRowStart->member.para.next_para
&& !cursor.nOffset && !cursor.pRun->member.run.nCharOfs) && !cursor.nOffset && !cursor.pRun->member.run.nCharOfs)
{ {
@ -860,7 +860,7 @@ void ME_RTFTblAttrHook(RTF_Info *info)
if (cellNum < MAX_TAB_STOPS) { if (cellNum < MAX_TAB_STOPS) {
/* Tab stops were used to store cell positions before v4.1 but v4.1 /* Tab stops were used to store cell positions before v4.1 but v4.1
* still seems to set the tabstops without using them. */ * still seems to set the tabstops without using them. */
ME_DisplayItem *para = ME_GetParagraph(info->editor->pCursors[0].pRun); ME_DisplayItem *para = info->editor->pCursors[0].pPara;
PARAFORMAT2 *pFmt = para->member.para.pFmt; PARAFORMAT2 *pFmt = para->member.para.pFmt;
pFmt->rgxTabs[cellNum] &= ~0x00FFFFFF; pFmt->rgxTabs[cellNum] &= ~0x00FFFFFF;
pFmt->rgxTabs[cellNum] = 0x00FFFFFF & info->rtfParam; pFmt->rgxTabs[cellNum] = 0x00FFFFFF & info->rtfParam;
@ -931,7 +931,7 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
ME_InsertTableCellFromCursor(info->editor); ME_InsertTableCellFromCursor(info->editor);
} }
} else { /* v1.0 - v3.0 */ } else { /* v1.0 - v3.0 */
ME_DisplayItem *para = ME_GetParagraph(info->editor->pCursors[0].pRun); ME_DisplayItem *para = info->editor->pCursors[0].pPara;
PARAFORMAT2 *pFmt = para->member.para.pFmt; PARAFORMAT2 *pFmt = para->member.para.pFmt;
if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE && if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE &&
tableDef->numCellsInserted < tableDef->numCellsDefined) tableDef->numCellsInserted < tableDef->numCellsDefined)
@ -1009,6 +1009,7 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
int nOfs, nChars; int nOfs, nChars;
/* Delete inserted cells that aren't defined. */ /* Delete inserted cells that aren't defined. */
info->editor->pCursors[1].pRun = run; info->editor->pCursors[1].pRun = run;
info->editor->pCursors[1].pPara = ME_GetParagraph(run);
info->editor->pCursors[1].nOffset = 0; info->editor->pCursors[1].nOffset = 0;
nOfs = ME_GetCursorOfs(info->editor, 1); nOfs = ME_GetCursorOfs(info->editor, 1);
nChars = ME_GetCursorOfs(info->editor, 0) - nOfs; nChars = ME_GetCursorOfs(info->editor, 0) - nOfs;
@ -1038,12 +1039,11 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
} }
} else { /* v1.0 - v3.0 */ } else { /* v1.0 - v3.0 */
WCHAR endl = '\r'; WCHAR endl = '\r';
ME_DisplayItem *para = ME_GetParagraph(info->editor->pCursors[0].pRun); ME_DisplayItem *para = info->editor->pCursors[0].pPara;
PARAFORMAT2 *pFmt = para->member.para.pFmt; PARAFORMAT2 *pFmt = para->member.para.pFmt;
pFmt->dxOffset = info->tableDef->gapH; pFmt->dxOffset = info->tableDef->gapH;
pFmt->dxStartIndent = info->tableDef->leftEdge; pFmt->dxStartIndent = info->tableDef->leftEdge;
para = ME_GetParagraph(info->editor->pCursors[0].pRun);
ME_ApplyBorderProperties(info, &para->member.para.border, ME_ApplyBorderProperties(info, &para->member.para.border,
tableDef->border); tableDef->border);
while (tableDef->numCellsInserted < tableDef->numCellsDefined) while (tableDef->numCellsInserted < tableDef->numCellsDefined)
@ -1066,7 +1066,7 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
ME_DisplayItem *para; ME_DisplayItem *para;
PARAFORMAT2 *pFmt; PARAFORMAT2 *pFmt;
RTFFlushOutputBuffer(info); RTFFlushOutputBuffer(info);
para = ME_GetParagraph(info->editor->pCursors[0].pRun); para = info->editor->pCursors[0].pPara;
pFmt = para->member.para.pFmt; pFmt = para->member.para.pFmt;
if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE)
{ {
@ -1404,16 +1404,18 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
/* Don't insert text at the end of the table row */ /* Don't insert text at the end of the table row */
if (!editor->bEmulateVersion10) { /* v4.1 */ if (!editor->bEmulateVersion10) { /* v4.1 */
ME_DisplayItem *para = ME_GetParagraph(editor->pCursors->pRun); ME_DisplayItem *para = editor->pCursors->pPara;
if (para->member.para.nFlags & MEPF_ROWEND) if (para->member.para.nFlags & MEPF_ROWEND)
{ {
para = para->member.para.next_para; para = para->member.para.next_para;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
} }
if (para->member.para.nFlags & MEPF_ROWSTART) if (para->member.para.nFlags & MEPF_ROWSTART)
{ {
para = para->member.para.next_para; para = para->member.para.next_para;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
} }
@ -1425,16 +1427,13 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
} }
} }
else { else {
ME_DisplayItem *para_item;
style = editor->pBuffer->pDefaultStyle; style = editor->pBuffer->pDefaultStyle;
ME_AddRefStyle(style); ME_AddRefStyle(style);
ME_SetSelection(editor, 0, 0); ME_SetSelection(editor, 0, 0);
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE); ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
from = to = 0; from = to = 0;
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
ME_SetDefaultParaFormat(editor->pCursors[0].pPara->member.para.pFmt);
para_item = ME_GetParagraph(editor->pCursors[0].pRun);
ME_SetDefaultParaFormat(para_item->member.para.pFmt);
} }
@ -1517,6 +1516,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
} }
pCell = para->member.para.pCell; pCell = para->member.para.pCell;
editor->pCursors[1].pPara = para;
editor->pCursors[1].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[1].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[1].nOffset = 0; editor->pCursors[1].nOffset = 0;
nOfs = ME_GetCursorOfs(editor, 1); nOfs = ME_GetCursorOfs(editor, 1);
@ -1637,7 +1637,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
TRACE("flags==0x%08x, chrg->cpMin==%d, chrg->cpMax==%d text==%s\n", TRACE("flags==0x%08x, chrg->cpMin==%d, chrg->cpMax==%d text==%s\n",
flags, chrg->cpMin, chrg->cpMax, debugstr_w(text)); flags, chrg->cpMin, chrg->cpMax, debugstr_w(text));
if (flags & ~(FR_DOWN | FR_MATCHCASE | FR_WHOLEWORD)) if (flags & ~(FR_DOWN | FR_MATCHCASE | FR_WHOLEWORD))
FIXME("Flags 0x%08x not implemented\n", FIXME("Flags 0x%08x not implemented\n",
flags & ~(FR_DOWN | FR_MATCHCASE | FR_WHOLEWORD)); flags & ~(FR_DOWN | FR_MATCHCASE | FR_WHOLEWORD));
@ -1647,7 +1647,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
nMax = nTextLen; nMax = nTextLen;
else else
nMax = chrg->cpMax > nTextLen ? nTextLen : chrg->cpMax; nMax = chrg->cpMax > nTextLen ? nTextLen : chrg->cpMax;
/* In 1.0 emulation, if cpMax reaches end of text, add the FR_DOWN flag */ /* In 1.0 emulation, if cpMax reaches end of text, add the FR_DOWN flag */
if (editor->bEmulateVersion10 && nMax == nTextLen) if (editor->bEmulateVersion10 && nMax == nTextLen)
{ {
@ -1687,33 +1687,18 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
chrgText->cpMin = chrgText->cpMax = -1; chrgText->cpMin = chrgText->cpMax = -1;
return -1; return -1;
} }
if (flags & FR_DOWN) /* Forward search */ if (flags & FR_DOWN) /* Forward search */
{ {
/* If possible, find the character before where the search starts */ /* If possible, find the character before where the search starts */
if ((flags & FR_WHOLEWORD) && nMin) if ((flags & FR_WHOLEWORD) && nMin)
{ {
nStart = nMin - 1; ME_RunOfsFromCharOfs(editor, nMin - 1, NULL, &item, &nStart);
ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
if (!item)
{
if (chrgText)
chrgText->cpMin = chrgText->cpMax = -1;
return -1;
}
wLastChar = item->member.run.strText->szData[nStart]; wLastChar = item->member.run.strText->szData[nStart];
} }
nStart = nMin; ME_RunOfsFromCharOfs(editor, nMin, &para, &item, &nStart);
ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
if (!item)
{
if (chrgText)
chrgText->cpMin = chrgText->cpMax = -1;
return -1;
}
para = ME_GetParagraph(item);
while (item while (item
&& para->member.para.nCharOfs + item->member.run.nCharOfs + nStart + nLen <= nMax) && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart + nLen <= nMax)
{ {
@ -1736,7 +1721,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
/* Check to see if next character is a whitespace */ /* Check to see if next character is a whitespace */
if (flags & FR_WHOLEWORD) if (flags & FR_WHOLEWORD)
{ {
if (nCurStart + nMatched == ME_StrLen(pCurItem->member.run.strText)) if (nCurStart + nMatched == pCurItem->member.run.strText->nLen)
{ {
pNextItem = ME_FindItemFwd(pCurItem, diRun); pNextItem = ME_FindItemFwd(pCurItem, diRun);
nNextStart = -nMatched; nNextStart = -nMatched;
@ -1760,10 +1745,9 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
TRACE("found at %d-%d\n", nStart, nStart + nLen); TRACE("found at %d-%d\n", nStart, nStart + nLen);
return nStart; return nStart;
} }
if (nCurStart + nMatched == ME_StrLen(pCurItem->member.run.strText)) if (nCurStart + nMatched == pCurItem->member.run.strText->nLen)
{ {
pCurItem = ME_FindItemFwd(pCurItem, diRun); pCurItem = ME_FindItemFwd(pCurItem, diRun);
para = ME_GetParagraph(pCurItem);
nCurStart = -nMatched; nCurStart = -nMatched;
} }
} }
@ -1773,7 +1757,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
wLastChar = ' '; wLastChar = ' ';
nStart++; nStart++;
if (nStart == ME_StrLen(item->member.run.strText)) if (nStart == item->member.run.strText->nLen)
{ {
item = ME_FindItemFwd(item, diRun); item = ME_FindItemFwd(item, diRun);
para = ME_GetParagraph(item); para = ME_GetParagraph(item);
@ -1786,42 +1770,25 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
/* If possible, find the character after where the search ends */ /* If possible, find the character after where the search ends */
if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1) if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1)
{ {
nEnd = nMax + 1; ME_RunOfsFromCharOfs(editor, nMax + 1, NULL, &item, &nEnd);
ME_RunOfsFromCharOfs(editor, nEnd, &item, &nEnd);
if (!item)
{
if (chrgText)
chrgText->cpMin = chrgText->cpMax = -1;
return -1;
}
wLastChar = item->member.run.strText->szData[nEnd]; wLastChar = item->member.run.strText->szData[nEnd];
} }
nEnd = nMax; ME_RunOfsFromCharOfs(editor, nMax, &para, &item, &nEnd);
ME_RunOfsFromCharOfs(editor, nEnd, &item, &nEnd);
if (!item)
{
if (chrgText)
chrgText->cpMin = chrgText->cpMax = -1;
return -1;
}
para = ME_GetParagraph(item);
while (item while (item
&& para->member.para.nCharOfs + item->member.run.nCharOfs + nEnd - nLen >= nMin) && para->member.para.nCharOfs + item->member.run.nCharOfs + nEnd - nLen >= nMin)
{ {
ME_DisplayItem *pCurItem = item; ME_DisplayItem *pCurItem = item;
int nCurEnd = nEnd; int nCurEnd = nEnd;
int nMatched = 0; int nMatched = 0;
if (nCurEnd - nMatched == 0) if (nCurEnd == 0)
{ {
pCurItem = ME_FindItemBack(pCurItem, diRun); pCurItem = ME_FindItemBack(pCurItem, diRun);
para = ME_GetParagraph(pCurItem); nCurEnd = pCurItem->member.run.strText->nLen + nMatched;
nCurEnd = ME_StrLen(pCurItem->member.run.strText) + nMatched;
} }
while (pCurItem && ME_CharCompare(pCurItem->member.run.strText->szData[nCurEnd - nMatched - 1], text[nLen - nMatched - 1], (flags & FR_MATCHCASE))) while (pCurItem && ME_CharCompare(pCurItem->member.run.strText->szData[nCurEnd - nMatched - 1], text[nLen - nMatched - 1], (flags & FR_MATCHCASE)))
{ {
if ((flags & FR_WHOLEWORD) && isalnumW(wLastChar)) if ((flags & FR_WHOLEWORD) && isalnumW(wLastChar))
@ -1841,7 +1808,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
{ {
pPrevItem = ME_FindItemBack(pCurItem, diRun); pPrevItem = ME_FindItemBack(pCurItem, diRun);
if (pPrevItem) if (pPrevItem)
nPrevEnd = ME_StrLen(pPrevItem->member.run.strText) + nMatched; nPrevEnd = pPrevItem->member.run.strText->nLen + nMatched;
} }
if (pPrevItem) if (pPrevItem)
@ -1853,7 +1820,8 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
break; break;
} }
nStart = para->member.para.nCharOfs + pCurItem->member.run.nCharOfs + nCurEnd - nMatched; nStart = ME_GetParagraph(pCurItem)->member.para.nCharOfs
+ pCurItem->member.run.nCharOfs + nCurEnd - nMatched;
if (chrgText) if (chrgText)
{ {
chrgText->cpMin = nStart; chrgText->cpMin = nStart;
@ -1867,8 +1835,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
pCurItem = ME_FindItemBack(pCurItem, diRun); pCurItem = ME_FindItemBack(pCurItem, diRun);
/* Don't care about pCurItem becoming NULL here; it's already taken /* Don't care about pCurItem becoming NULL here; it's already taken
* care of in the exterior loop condition */ * care of in the exterior loop condition */
para = ME_GetParagraph(pCurItem); nCurEnd = pCurItem->member.run.strText->nLen + nMatched;
nCurEnd = ME_StrLen(pCurItem->member.run.strText) + nMatched;
} }
} }
if (pCurItem) if (pCurItem)
@ -1881,7 +1848,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
{ {
item = ME_FindItemBack(item, diRun); item = ME_FindItemBack(item, diRun);
para = ME_GetParagraph(item); para = ME_GetParagraph(item);
nEnd = ME_StrLen(item->member.run.strText); nEnd = item->member.run.strText->nLen;
} }
} }
} }
@ -1939,20 +1906,16 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
} }
} }
static int ME_GetTextRange(ME_TextEditor *editor, TEXTRANGEW *rng, BOOL unicode) static int ME_GetTextRange(ME_TextEditor *editor, WCHAR *strText,
int start, int nLen, BOOL unicode)
{ {
if (unicode) if (unicode) {
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, return ME_GetTextW(editor, strText, start, nLen, 0);
rng->chrg.cpMax-rng->chrg.cpMin, 0); } else {
else
{
int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1); WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, 0); int nChars = ME_GetTextW(editor, p, start, nLen, 0);
/* FIXME this is a potential security hole (buffer overrun) WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)strText,
if you know more about wchar->mbyte conversion please explain nLen+1, NULL, NULL);
*/
WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)rng->lpstrText, nLen+1, NULL, NULL);
FREE_OBJ(p); FREE_OBJ(p);
return nChars; return nChars;
} }
@ -2051,11 +2014,14 @@ ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
{ {
MSGFILTER msgf; MSGFILTER msgf;
if (!editor->hWnd) return FALSE;
msgf.nmhdr.hwndFrom = editor->hWnd;
msgf.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
msgf.nmhdr.code = EN_MSGFILTER; msgf.nmhdr.code = EN_MSGFILTER;
msgf.msg = msg; msgf.msg = msg;
msgf.wParam = *wParam; msgf.wParam = *wParam;
msgf.lParam = *lParam; msgf.lParam = *lParam;
if (ITextHost_TxNotify(editor->texthost, msgf.nmhdr.code, &msgf) == S_OK) if (SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf))
return FALSE; return FALSE;
*wParam = msgf.wParam; *wParam = msgf.wParam;
*lParam = msgf.lParam; *lParam = msgf.lParam;
@ -2066,40 +2032,26 @@ ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor) static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
{ {
ME_DisplayItem * startPara, * endPara; ME_DisplayItem *startPara, *endPara;
ME_DisplayItem * item; ME_DisplayItem *prev_para;
ME_Cursor cursor;
int from, to; int from, to;
if (!editor->AutoURLDetect_bEnable) return;
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
if (from > to) from ^= to, to ^=from, from ^= to;
startPara = NULL; endPara = NULL;
/* Find paragraph previous to the one that contains start cursor */ /* Find paragraph previous to the one that contains start cursor */
ME_CursorFromCharOfs(editor, from, &cursor); ME_RunOfsFromCharOfs(editor, from, &startPara, NULL, NULL);
item = cursor.pRun; prev_para = startPara->member.para.prev_para;
if (item) { if (prev_para->type == diParagraph) startPara = prev_para;
startPara = ME_FindItemBack(item, diParagraph);
item = startPara->member.para.prev_para;
if (item && item->type == diParagraph) startPara = item;
}
/* Find paragraph that contains end cursor */ /* Find paragraph that contains end cursor */
ME_CursorFromCharOfs(editor, to, &cursor); ME_RunOfsFromCharOfs(editor, to, &endPara, NULL, NULL);
item = cursor.pRun; endPara = endPara->member.para.next_para;
if (item) {
endPara = ME_FindItemFwd(item, diParagraph);
}
if (startPara && endPara) { ME_UpdateLinkAttribute(editor,
ME_UpdateLinkAttribute(editor, startPara->member.para.nCharOfs,
startPara->member.para.nCharOfs, endPara->member.para.nCharOfs);
endPara->member.para.nCharOfs);
} else if (startPara) {
ME_UpdateLinkAttribute(editor,
startPara->member.para.nCharOfs,
-1);
}
} }
static BOOL static BOOL
@ -2171,7 +2123,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
if (editor->styleFlags & ES_MULTILINE) if (editor->styleFlags & ES_MULTILINE)
{ {
ME_Cursor cursor = editor->pCursors[0]; ME_Cursor cursor = editor->pCursors[0];
ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); ME_DisplayItem *para = cursor.pPara;
int from, to; int from, to;
const WCHAR endl = '\r'; const WCHAR endl = '\r';
ME_Style *style; ME_Style *style;
@ -2189,6 +2141,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
/* Add a new table row after this row. */ /* Add a new table row after this row. */
para = ME_AppendTableRow(editor, para); para = ME_AppendTableRow(editor, para);
para = para->member.para.next_para; para = para->member.para.next_para;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -2197,7 +2150,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
return TRUE; return TRUE;
} }
else if (para == ME_GetParagraph(editor->pCursors[1].pRun) && else if (para == editor->pCursors[1].pPara &&
cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 && 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.nFlags & MEPF_ROWSTART &&
!para->member.para.prev_para->member.para.nCharOfs) !para->member.para.prev_para->member.para.nCharOfs)
@ -2205,6 +2158,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
/* Insert a newline before the table. */ /* Insert a newline before the table. */
para = para->member.para.prev_para; para = para->member.para.prev_para;
para->member.para.nFlags &= ~MEPF_ROWSTART; para->member.para.nFlags &= ~MEPF_ROWSTART;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
ME_InsertTextFromCursor(editor, 0, &endl, 1, ME_InsertTextFromCursor(editor, 0, &endl, 1,
@ -2212,6 +2166,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
para = editor->pBuffer->pFirst->member.para.next_para; para = editor->pBuffer->pFirst->member.para.next_para;
ME_SetDefaultParaFormat(para->member.para.pFmt); ME_SetDefaultParaFormat(para->member.para.pFmt);
para->member.para.nFlags = MEPF_REWRAP; para->member.para.nFlags = MEPF_REWRAP;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART; para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART;
@ -2221,7 +2176,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
return TRUE; return TRUE;
} }
} else { /* v1.0 - 3.0 */ } else { /* v1.0 - 3.0 */
ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); ME_DisplayItem *para = cursor.pPara;
if (ME_IsInTable(para)) if (ME_IsInTable(para))
{ {
if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
@ -2229,6 +2184,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
if (from == to) { if (from == to) {
ME_ContinueCoalescingTransaction(editor); ME_ContinueCoalescingTransaction(editor);
para = ME_AppendTableRow(editor, para); para = ME_AppendTableRow(editor, para);
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -2243,8 +2199,10 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
{ {
/* Insert newline before table */ /* Insert newline before table */
cursor.pRun = ME_FindItemBack(para, diRun); cursor.pRun = ME_FindItemBack(para, diRun);
if (cursor.pRun) if (cursor.pRun) {
editor->pCursors[0].pRun = cursor.pRun; editor->pCursors[0].pRun = cursor.pRun;
editor->pCursors[0].pPara = para->member.para.prev_para;
}
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
ME_InsertTextFromCursor(editor, 0, &endl, 1, ME_InsertTextFromCursor(editor, 0, &endl, 1,
@ -2252,6 +2210,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
} else { } else {
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
para = ME_AppendTableRow(editor, para); para = ME_AppendTableRow(editor, para);
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -2274,9 +2233,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
ME_CommitCoalescingUndo(editor); ME_CommitCoalescingUndo(editor);
SetCursor(NULL); SetCursor(NULL);
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
ME_UpdateSelectionLinkAttribute(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
} }
return TRUE; return TRUE;
@ -2374,7 +2331,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
if ((unsigned)wstr >= ' ' || wstr == '\t') if ((unsigned)wstr >= ' ' || wstr == '\t')
{ {
ME_Cursor cursor = editor->pCursors[0]; ME_Cursor cursor = editor->pCursors[0];
ME_DisplayItem *para = ME_GetParagraph(cursor.pRun); ME_DisplayItem *para = cursor.pPara;
int from, to; int from, to;
BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
@ -2385,7 +2342,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
ME_DisplayItem *para; ME_DisplayItem *para;
BOOL bSelectedRow = FALSE; BOOL bSelectedRow = FALSE;
para = ME_GetParagraph(cursor.pRun); para = cursor.pPara;
if (ME_IsSelection(editor) && if (ME_IsSelection(editor) &&
cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
to == ME_GetCursorOfs(editor, 0) && to == ME_GetCursorOfs(editor, 0) &&
@ -2406,6 +2363,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
para = para->member.para.next_para; para = para->member.para.next_para;
if (para->member.para.nFlags & MEPF_ROWSTART) if (para->member.para.nFlags & MEPF_ROWSTART)
para = para->member.para.next_para; para = para->member.para.next_para;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -2434,8 +2392,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
ITextHost_TxSetCursor(editor->texthost, NULL, FALSE); ITextHost_TxSetCursor(editor->texthost, NULL, FALSE);
} }
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); ME_UpdateSelectionLinkAttribute(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
} }
return 0; return 0;
@ -2556,22 +2513,20 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
offset = ME_CharFromPos(editor, pt.x, pt.y, &isExact); offset = ME_CharFromPos(editor, pt.x, pt.y, &isExact);
if (isExact) if (isExact)
{ {
if (editor->AutoURLDetect_bEnable) ME_Cursor cursor;
ME_Run *run;
ME_CursorFromCharOfs(editor, offset, &cursor);
run = &cursor.pRun->member.run;
if (run->style->fmt.dwMask & CFM_LINK &&
run->style->fmt.dwEffects & CFE_LINK)
{ {
ME_Cursor cursor; ITextHost_TxSetCursor(editor->texthost,
ME_Run *run; LoadCursorW(NULL, (WCHAR*)IDC_HAND),
ME_CursorFromCharOfs(editor, offset, &cursor); FALSE);
run = &cursor.pRun->member.run; return TRUE;
if (editor->AutoURLDetect_bEnable &&
run->style->fmt.dwMask & CFM_LINK &&
run->style->fmt.dwEffects & CFE_LINK)
{
ITextHost_TxSetCursor(editor->texthost,
LoadCursorW(NULL, (WCHAR*)IDC_HAND),
FALSE);
return TRUE;
}
} }
if (ME_IsSelection(editor)) if (ME_IsSelection(editor))
{ {
int selStart, selEnd; int selStart, selEnd;
@ -2653,10 +2608,10 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
*/ */
ed->nCursors = 4; ed->nCursors = 4;
ed->pCursors = ALLOC_N_OBJ(ME_Cursor, ed->nCursors); ed->pCursors = ALLOC_N_OBJ(ME_Cursor, ed->nCursors);
ed->pCursors[0].pRun = ME_FindItemFwd(ed->pBuffer->pFirst, diRun); ed->pCursors[0].pPara = ed->pBuffer->pFirst->member.para.next_para;
ed->pCursors[0].pRun = ME_FindItemFwd(ed->pCursors[0].pPara, diRun);
ed->pCursors[0].nOffset = 0; ed->pCursors[0].nOffset = 0;
ed->pCursors[1].pRun = ME_FindItemFwd(ed->pBuffer->pFirst, diRun); ed->pCursors[1] = ed->pCursors[0];
ed->pCursors[1].nOffset = 0;
ed->pCursors[2] = ed->pCursors[0]; ed->pCursors[2] = ed->pCursors[0];
ed->pCursors[3] = ed->pCursors[1]; ed->pCursors[3] = ed->pCursors[1];
ed->nLastTotalLength = ed->nTotalLength = 0; ed->nLastTotalLength = ed->nTotalLength = 0;
@ -2676,11 +2631,11 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->nParagraphs = 1; ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0; ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph); ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph);
ed->bWordWrap = (props & TXTBIT_WORDWRAP) != 0; ed->nAvailWidth = 0; /* wrap to client area */
ed->bHideSelection = FALSE; ed->bHideSelection = FALSE;
ed->pfnWordBreak = NULL; ed->pfnWordBreak = NULL;
ed->lpOleCallback = NULL; ed->lpOleCallback = NULL;
ed->mode = TM_RICHTEXT | TM_MULTILEVELUNDO | TM_MULTICODEPAGE; ed->mode = TM_MULTILEVELUNDO | TM_MULTICODEPAGE;
ed->mode |= (props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT; ed->mode |= (props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT;
ed->AutoURLDetect_bEnable = FALSE; ed->AutoURLDetect_bEnable = FALSE;
ed->bHaveFocus = FALSE; ed->bHaveFocus = FALSE;
@ -2695,8 +2650,13 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ME_CheckCharOffsets(ed); ME_CheckCharOffsets(ed);
ed->bDefaultFormatRect = TRUE; ed->bDefaultFormatRect = TRUE;
ITextHost_TxGetSelectionBarWidth(ed->texthost, &selbarwidth); ITextHost_TxGetSelectionBarWidth(ed->texthost, &selbarwidth);
/* FIXME: Convert selbarwidth from HIMETRIC to pixels */ if (selbarwidth) {
ed->selofs = selbarwidth ? SELECTIONBAR_WIDTH : 0; /* FIXME: Convert selbarwidth from HIMETRIC to pixels */
ed->selofs = SELECTIONBAR_WIDTH;
ed->styleFlags |= ES_SELECTIONBAR;
} else {
ed->selofs = 0;
}
ed->nSelectionType = stPosition; ed->nSelectionType = stPosition;
ed->cPasswordMask = 0; ed->cPasswordMask = 0;
@ -2705,8 +2665,12 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
if (props & TXTBIT_AUTOWORDSEL) if (props & TXTBIT_AUTOWORDSEL)
ed->styleFlags |= ECO_AUTOWORDSELECTION; ed->styleFlags |= ECO_AUTOWORDSELECTION;
if (props & TXTBIT_MULTILINE) if (props & TXTBIT_MULTILINE) {
ed->styleFlags |= ES_MULTILINE; ed->styleFlags |= ES_MULTILINE;
ed->bWordWrap = (props & TXTBIT_WORDWRAP) != 0;
} else {
ed->bWordWrap = FALSE;
}
if (props & TXTBIT_READONLY) if (props & TXTBIT_READONLY)
ed->styleFlags |= ES_READONLY; ed->styleFlags |= ES_READONLY;
if (!(props & TXTBIT_HIDESELECTION)) if (!(props & TXTBIT_HIDESELECTION))
@ -2940,23 +2904,20 @@ get_msg_name(UINT msg)
void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam) void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
int x,y; int x,y;
ME_Cursor tmpCursor; ME_DisplayItem *para, *run;
BOOL isExact; BOOL isExact;
int nCharOfs; /* The start of the clicked text. Absolute character offset */ int nCharOfs; /* The start of the clicked text. Absolute character offset */
ME_Run *tmpRun;
ENLINK info; ENLINK info;
x = (short)LOWORD(lParam); x = (short)LOWORD(lParam);
y = (short)HIWORD(lParam); y = (short)HIWORD(lParam);
nCharOfs = ME_CharFromPos(editor, x, y, &isExact); nCharOfs = ME_CharFromPos(editor, x, y, &isExact);
if (!isExact) return; if (!isExact) return;
ME_CursorFromCharOfs(editor, nCharOfs, &tmpCursor); ME_RunOfsFromCharOfs(editor, nCharOfs, &para, &run, NULL);
tmpRun = &tmpCursor.pRun->member.run;
if ((tmpRun->style->fmt.dwMask & CFM_LINK) if ((run->member.run.style->fmt.dwMask & CFM_LINK)
&& (tmpRun->style->fmt.dwEffects & CFE_LINK)) && (run->member.run.style->fmt.dwEffects & CFE_LINK))
{ /* The clicked run has CFE_LINK set */ { /* The clicked run has CFE_LINK set */
info.nmhdr.hwndFrom = editor->hWnd; info.nmhdr.hwndFrom = editor->hWnd;
info.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID); info.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
@ -2964,8 +2925,8 @@ void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam
info.msg = msg; info.msg = msg;
info.wParam = wParam; info.wParam = wParam;
info.lParam = lParam; info.lParam = lParam;
info.chrg.cpMin = ME_CharOfsFromRunOfs(editor,tmpCursor.pRun,0); info.chrg.cpMin = ME_CharOfsFromRunOfs(editor, para, run, 0);
info.chrg.cpMax = info.chrg.cpMin + ME_StrVLen(tmpRun->strText); info.chrg.cpMax = info.chrg.cpMin + run->member.run.strText->nLen;
SendMessageW(GetParent(editor->hWnd), WM_NOTIFY,info.nmhdr.idFrom, (LPARAM)&info); SendMessageW(GetParent(editor->hWnd), WM_NOTIFY,info.nmhdr.idFrom, (LPARAM)&info);
} }
} }
@ -2999,7 +2960,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
UNSUPPORTED_MSG(EM_SETIMESTATUS) UNSUPPORTED_MSG(EM_SETIMESTATUS)
UNSUPPORTED_MSG(EM_GETLANGOPTIONS) UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
UNSUPPORTED_MSG(EM_GETREDONAME) UNSUPPORTED_MSG(EM_GETREDONAME)
UNSUPPORTED_MSG(EM_GETTEXTMODE)
UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS) UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
UNSUPPORTED_MSG(EM_GETUNDONAME) UNSUPPORTED_MSG(EM_GETUNDONAME)
UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX) UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX)
@ -3108,31 +3068,36 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
} }
changedSettings = oldSettings ^ settings; changedSettings = oldSettings ^ settings;
if (oldSettings ^ settings) { if (changedSettings) {
editor->styleFlags = (editor->styleFlags & ~mask) | (settings & mask); editor->styleFlags = (editor->styleFlags & ~mask) | (settings & mask);
if (settings & ECO_SELECTIONBAR) { if (changedSettings & ECO_SELECTIONBAR)
editor->selofs = SELECTIONBAR_WIDTH; {
editor->rcFormat.left += SELECTIONBAR_WIDTH; ITextHost_TxInvalidateRect(editor->texthost, &editor->rcFormat, TRUE);
} else { if (settings & ECO_SELECTIONBAR) {
editor->selofs = 0; assert(!editor->selofs);
editor->rcFormat.left -= SELECTIONBAR_WIDTH; editor->selofs = SELECTIONBAR_WIDTH;
editor->rcFormat.left += editor->selofs;
} else {
editor->rcFormat.left -= editor->selofs;
editor->selofs = 0;
}
ME_RewrapRepaint(editor);
} }
ME_WrapMarkedParagraphs(editor);
}
if (settings & ECO_VERTICAL) if (changedSettings & settings & ECO_VERTICAL)
FIXME("ECO_VERTICAL not implemented yet!\n"); FIXME("ECO_VERTICAL not implemented yet!\n");
if (settings & ECO_AUTOHSCROLL) if (changedSettings & settings & ECO_AUTOHSCROLL)
FIXME("ECO_AUTOHSCROLL not implemented yet!\n"); FIXME("ECO_AUTOHSCROLL not implemented yet!\n");
if (settings & ECO_AUTOVSCROLL) if (changedSettings & settings & ECO_AUTOVSCROLL)
FIXME("ECO_AUTOVSCROLL not implemented yet!\n"); FIXME("ECO_AUTOVSCROLL not implemented yet!\n");
if (settings & ECO_NOHIDESEL) if (changedSettings & settings & ECO_NOHIDESEL)
FIXME("ECO_NOHIDESEL not implemented yet!\n"); FIXME("ECO_NOHIDESEL not implemented yet!\n");
if (settings & ECO_WANTRETURN) if (changedSettings & settings & ECO_WANTRETURN)
FIXME("ECO_WANTRETURN not implemented yet!\n"); FIXME("ECO_WANTRETURN not implemented yet!\n");
if (settings & ECO_AUTOWORDSELECTION) if (changedSettings & settings & ECO_AUTOWORDSELECTION)
FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n"); FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
}
return settings; return settings;
} }
@ -3200,12 +3165,18 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return 0; return 0;
} }
if (lParam) if (lParam) {
editor->styleFlags |= flags; editor->styleFlags |= flags;
else if (flags & WS_HSCROLL)
editor->styleFlags &= flags; ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
editor->nTotalWidth > editor->sizeWindow.cx);
ITextHost_TxShowScrollBar(editor->texthost, wParam, lParam); if (flags & WS_VSCROLL)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
editor->nTotalLength > editor->sizeWindow.cy);
} else {
editor->styleFlags &= ~flags;
ITextHost_TxShowScrollBar(editor->texthost, wParam, FALSE);
}
return 0; return 0;
} }
case EM_SETTEXTEX: case EM_SETTEXTEX:
@ -3256,12 +3227,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
if (bSelection) { if (bSelection) {
ME_ReleaseStyle(style); ME_ReleaseStyle(style);
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
ME_UpdateSelectionLinkAttribute(editor);
} else { } else {
len = 1; len = 1;
if (editor->AutoURLDetect_bEnable) ME_UpdateLinkAttribute(editor, 0, -1);
ME_UpdateLinkAttribute(editor, 0, -1);
} }
ME_CommitUndo(editor); ME_CommitUndo(editor);
if (!(pStruct->flags & ST_KEEPUNDO)) if (!(pStruct->flags & ST_KEEPUNDO))
@ -3419,8 +3388,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
} }
case EM_LINESCROLL: case EM_LINESCROLL:
{ {
if (!(editor->styleFlags & ES_MULTILINE))
return FALSE;
ME_ScrollDown(editor, lParam * 8); /* FIXME follow the original */ ME_ScrollDown(editor, lParam * 8); /* FIXME follow the original */
return TRUE; /* Should return false if a single line richedit control */ return TRUE;
} }
case WM_CLEAR: case WM_CLEAR:
{ {
@ -3453,7 +3424,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
ME_EndToUnicode(unicode, wszText); ME_EndToUnicode(unicode, wszText);
ME_CommitUndo(editor); ME_CommitUndo(editor);
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); ME_UpdateSelectionLinkAttribute(editor);
if (!wParam) if (!wParam)
ME_EmptyUndoStack(editor); ME_EmptyUndoStack(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
@ -3468,7 +3439,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
CHARFORMAT2W fmt; CHARFORMAT2W fmt;
HDC hDC; HDC hDC;
BOOL bRepaint = LOWORD(lParam); BOOL bRepaint = LOWORD(lParam);
if (!wParam) if (!wParam)
wParam = (WPARAM)GetStockObject(SYSTEM_FONT); wParam = (WPARAM)GetStockObject(SYSTEM_FONT);
GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf); GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf);
@ -3479,8 +3450,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_SetDefaultCharFormat(editor, &fmt); ME_SetDefaultCharFormat(editor, &fmt);
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_MarkAllForWrapping(editor);
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
if (bRepaint) if (bRepaint)
ME_RewrapRepaint(editor); ME_Repaint(editor);
return 0; return 0;
} }
case WM_SETTEXT: case WM_SETTEXT:
@ -3518,10 +3492,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
} }
else else
TRACE("WM_SETTEXT - NULL\n"); TRACE("WM_SETTEXT - NULL\n");
if (editor->AutoURLDetect_bEnable) ME_UpdateLinkAttribute(editor, 0, -1);
{
ME_UpdateLinkAttribute(editor, 0, -1);
}
ME_SetSelection(editor, 0, 0); ME_SetSelection(editor, 0, 0);
editor->nModifyStep = 0; editor->nModifyStep = 0;
ME_CommitUndo(editor); ME_CommitUndo(editor);
@ -3605,12 +3576,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_GETSELTEXT: case EM_GETSELTEXT:
{ {
int from, to; int from, to;
TEXTRANGEW tr; /* W and A differ only by rng->lpstrText */
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
tr.chrg.cpMin = from; return ME_GetTextRange(editor, (WCHAR *)lParam, from,
tr.chrg.cpMax = to; to - from, unicode);
tr.lpstrText = (WCHAR *)lParam;
return ME_GetTextRange(editor, &tr, unicode);
} }
case EM_GETSCROLLPOS: case EM_GETSCROLLPOS:
{ {
@ -3622,10 +3590,17 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_GETTEXTRANGE: case EM_GETTEXTRANGE:
{ {
TEXTRANGEW *rng = (TEXTRANGEW *)lParam; TEXTRANGEW *rng = (TEXTRANGEW *)lParam;
int start = rng->chrg.cpMin;
int end = rng->chrg.cpMax;
int textlength = ME_GetTextLength(editor);
TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d emul1.0=%d length=%d\n", TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d emul1.0=%d length=%d\n",
rng->chrg.cpMin, rng->chrg.cpMax, unicode, rng->chrg.cpMin, rng->chrg.cpMax, unicode,
editor->bEmulateVersion10, ME_GetTextLength(editor)); editor->bEmulateVersion10, ME_GetTextLength(editor));
return ME_GetTextRange(editor, rng, unicode); if (start < 0) return 0;
if ((start == 0 && end == -1) || end > textlength)
end = textlength;
if (start >= end) return 0;
return ME_GetTextRange(editor, rng->lpstrText, start, end - start, unicode);
} }
case EM_GETLINE: case EM_GETLINE:
{ {
@ -3743,7 +3718,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
{ {
ME_DisplayItem *item, *item_end; ME_DisplayItem *item, *item_end;
int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0; int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0;
ME_Cursor cursor; ME_DisplayItem *para, *run;
if (wParam > ME_GetTextLength(editor)) if (wParam > ME_GetTextLength(editor))
return 0; return 0;
@ -3752,23 +3727,16 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
FIXME("EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n"); FIXME("EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n");
return 0; return 0;
} }
ME_CursorFromCharOfs(editor, wParam, &cursor); ME_RunOfsFromCharOfs(editor, wParam, &para, &run, NULL);
item = ME_RowStart(cursor.pRun); item = ME_RowStart(run);
nThisLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item, diRun), 0); nThisLineOfs = ME_CharOfsFromRunOfs(editor, para, ME_FindItemFwd(item, diRun), 0);
item_end = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd); item_end = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd);
if (item_end->type == diStartRow) if (item_end->type == diStartRow) {
nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0); nNextLineOfs = ME_CharOfsFromRunOfs(editor, para, ME_FindItemFwd(item_end, diRun), 0);
else } else {
{ ME_DisplayItem *endRun = ME_FindItemBack(item_end, diRun);
ME_DisplayItem *endPara; assert(endRun && endRun->member.run.nFlags & MERF_ENDPARA);
nNextLineOfs = item_end->member.para.nCharOfs - endRun->member.run.strText->nLen;
nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs;
endPara = ME_FindItemFwd(item, diParagraphOrEnd);
endPara = ME_FindItemBack(endPara, diRun);
assert(endPara);
assert(endPara->type == diRun);
assert(endPara->member.run.nFlags & MERF_ENDPARA);
nNextLineOfs -= endPara->member.run.strText->nLen;
} }
nChars = nNextLineOfs - nThisLineOfs; nChars = nNextLineOfs - nThisLineOfs;
TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars); TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars);
@ -3844,7 +3812,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return ME_CharFromPos(editor, ((POINTL *)lParam)->x, ((POINTL *)lParam)->y, NULL); return ME_CharFromPos(editor, ((POINTL *)lParam)->x, ((POINTL *)lParam)->y, NULL);
case EM_POSFROMCHAR: case EM_POSFROMCHAR:
{ {
ME_DisplayItem *pRun; ME_DisplayItem *pPara, *pRun;
int nCharOfs, nOffset, nLength; int nCharOfs, nOffset, nLength;
POINTL pt = {0,0}; POINTL pt = {0,0};
@ -3856,11 +3824,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
nCharOfs = min(nCharOfs, nLength); nCharOfs = min(nCharOfs, nLength);
nCharOfs = max(nCharOfs, 0); nCharOfs = max(nCharOfs, 0);
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset); ME_RunOfsFromCharOfs(editor, nCharOfs, &pPara, &pRun, &nOffset);
assert(pRun->type == diRun); assert(pRun->type == diRun);
pt.y = pRun->member.run.pt.y; pt.y = pRun->member.run.pt.y;
pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset); pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset);
pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top; pt.y += pPara->member.para.pt.y + editor->rcFormat.top;
pt.x += editor->rcFormat.left; pt.x += editor->rcFormat.left;
pt.x -= editor->horz_si.nPos; pt.x -= editor->horz_si.nPos;
@ -4183,8 +4151,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_SetDefaultFormatRect(editor); ME_SetDefaultFormatRect(editor);
editor->bDefaultFormatRect = TRUE; editor->bDefaultFormatRect = TRUE;
} }
ME_MarkAllForWrapping(editor);
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
if (msg != EM_SETRECTNP) if (msg != EM_SETRECTNP)
ME_RewrapRepaint(editor); ME_Repaint(editor);
return 0; return 0;
} }
case EM_REQUESTRESIZE: case EM_REQUESTRESIZE:
@ -4290,6 +4261,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
editor->pfnWordBreak = (EDITWORDBREAKPROCW)lParam; editor->pfnWordBreak = (EDITWORDBREAKPROCW)lParam;
return (LRESULT)pfnOld; return (LRESULT)pfnOld;
} }
case EM_GETTEXTMODE:
return editor->mode;
case EM_SETTEXTMODE: case EM_SETTEXTMODE:
{ {
LRESULT ret; LRESULT ret;
@ -4331,15 +4304,25 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_SETTARGETDEVICE: case EM_SETTARGETDEVICE:
if (wParam == 0) if (wParam == 0)
{ {
BOOL new = (lParam == 0); BOOL new = (lParam == 0 && (editor->styleFlags & ES_MULTILINE));
if (editor->bWordWrap != new) if (editor->nAvailWidth || editor->bWordWrap != new)
{ {
editor->bWordWrap = new; editor->bWordWrap = new;
editor->nAvailWidth = 0; /* wrap to client area */
ME_RewrapRepaint(editor); ME_RewrapRepaint(editor);
} }
} else {
int width = max(0, lParam);
if ((editor->styleFlags & ES_MULTILINE) &&
(!editor->bWordWrap || editor->nAvailWidth != width))
{
editor->nAvailWidth = width;
editor->bWordWrap = TRUE;
ME_RewrapRepaint(editor);
}
FIXME("EM_SETTARGETDEVICE doesn't use non-NULL target devices\n");
} }
else FIXME("Unsupported yet non NULL device in EM_SETTARGETDEVICE\n"); return TRUE;
break;
default: default:
do_default: do_default:
*phresult = S_FALSE; *phresult = S_FALSE;
@ -4532,7 +4515,7 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart,
int nOffset, nWritten = 0; int nOffset, nWritten = 0;
WCHAR *pStart = buffer; WCHAR *pStart = buffer;
ME_RunOfsFromCharOfs(editor, nStart, &pRun, &nOffset); ME_RunOfsFromCharOfs(editor, nStart, NULL, &pRun, &nOffset);
/* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */ /* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */
if (editor->bEmulateVersion10) bCRLF = 0; if (editor->bEmulateVersion10) bCRLF = 0;
@ -4720,10 +4703,8 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_
TRACE("sel_min = %d sel_max = %d\n", sel_min, sel_max); TRACE("sel_min = %d sel_max = %d\n", sel_min, sel_max);
*candidate_min = *candidate_max = -1; *candidate_min = *candidate_max = -1;
ME_RunOfsFromCharOfs(editor, sel_min, &item, &nStart); ME_RunOfsFromCharOfs(editor, sel_min, &para, &item, &nStart);
if (!item) return FALSE;
TRACE("nStart = %d\n", nStart); TRACE("nStart = %d\n", nStart);
para = ME_GetParagraph(item);
if (sel_max == -1) sel_max = ME_GetTextLength(editor); if (sel_max == -1) sel_max = ME_GetTextLength(editor);
while (item && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart < sel_max) while (item && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart < sel_max)
{ {
@ -4732,12 +4713,12 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_
if (!(item->member.run.nFlags & MERF_ENDPARA)) { if (!(item->member.run.nFlags & MERF_ENDPARA)) {
/* Find start of candidate */ /* Find start of candidate */
if (*candidate_min == -1) { if (*candidate_min == -1) {
while (nStart < ME_StrLen(item->member.run.strText) && while (nStart < item->member.run.strText->nLen &&
!(isalnumW(item->member.run.strText->szData[nStart]) || !(isalnumW(item->member.run.strText->szData[nStart]) ||
isurlspecial(item->member.run.strText->szData[nStart]))) { isurlspecial(item->member.run.strText->szData[nStart]))) {
nStart++; nStart++;
} }
if (nStart < ME_StrLen(item->member.run.strText) && if (nStart < item->member.run.strText->nLen &&
(isalnumW(item->member.run.strText->szData[nStart]) || (isalnumW(item->member.run.strText->szData[nStart]) ||
isurlspecial(item->member.run.strText->szData[nStart]))) { isurlspecial(item->member.run.strText->szData[nStart]))) {
*candidate_min = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart; *candidate_min = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart;
@ -4748,7 +4729,7 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_
/* Find end of candidate */ /* Find end of candidate */
if (*candidate_min >= 0) { if (*candidate_min >= 0) {
while (nStart < ME_StrLen(item->member.run.strText) && while (nStart < item->member.run.strText->nLen &&
(isalnumW(item->member.run.strText->szData[nStart]) || (isalnumW(item->member.run.strText->szData[nStart]) ||
isurlspecial(item->member.run.strText->szData[nStart]) || isurlspecial(item->member.run.strText->szData[nStart]) ||
(!foundColon && item->member.run.strText->szData[nStart] == ':') )) { (!foundColon && item->member.run.strText->szData[nStart] == ':') )) {
@ -4756,7 +4737,7 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_
lastAcceptedChar = item->member.run.strText->szData[nStart]; lastAcceptedChar = item->member.run.strText->szData[nStart];
nStart++; nStart++;
} }
if (nStart < ME_StrLen(item->member.run.strText) && if (nStart < item->member.run.strText->nLen &&
!(isalnumW(item->member.run.strText->szData[nStart]) || !(isalnumW(item->member.run.strText->szData[nStart]) ||
isurlspecial(item->member.run.strText->szData[nStart]) )) { isurlspecial(item->member.run.strText->szData[nStart]) )) {
*candidate_max = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart; *candidate_max = para->member.para.nCharOfs + item->member.run.nCharOfs + nStart;
@ -4861,6 +4842,8 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_m
BOOL modified = FALSE; BOOL modified = FALSE;
int cMin, cMax; int cMin, cMax;
if (!editor->AutoURLDetect_bEnable) return FALSE;
if (sel_max == -1) sel_max = ME_GetTextLength(editor); if (sel_max == -1) sel_max = ME_GetTextLength(editor);
do do
{ {

View file

@ -70,7 +70,6 @@ void ME_ClearTempStyle(ME_TextEditor *editor);
void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048]); void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048]);
void ME_DumpStyle(ME_Style *s); void ME_DumpStyle(ME_Style *s);
CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from); CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from);
void ME_CopyToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from);
void ME_CopyToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from); void ME_CopyToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from);
void ME_CopyCharFormat(CHARFORMAT2W *pDest, const CHARFORMAT2W *pSrc); /* only works with 2W structs */ void ME_CopyCharFormat(CHARFORMAT2W *pDest, const CHARFORMAT2W *pSrc); /* only works with 2W structs */
void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt); /* ditto */ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt); /* ditto */
@ -81,7 +80,6 @@ void ME_Remove(ME_DisplayItem *diWhere);
ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass); ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass);
ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass); ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass);
ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass); ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass);
ME_DisplayItem *ME_FindItemFwdOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass);
ME_DisplayItem *ME_MakeDI(ME_DIType type); ME_DisplayItem *ME_MakeDI(ME_DIType type);
void ME_DestroyDisplayItem(ME_DisplayItem *item); void ME_DestroyDisplayItem(ME_DisplayItem *item);
void ME_DumpDocument(ME_TextBuffer *buffer); void ME_DumpDocument(ME_TextBuffer *buffer);
@ -91,26 +89,15 @@ const char *ME_GetDITypeName(ME_DIType type);
ME_String *ME_MakeString(LPCWSTR szText); ME_String *ME_MakeString(LPCWSTR szText);
ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars); ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars);
ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars); ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars);
ME_String *ME_MakeStringB(int nMaxChars);
ME_String *ME_StrDup(const ME_String *s); ME_String *ME_StrDup(const ME_String *s);
void ME_DestroyString(ME_String *s); void ME_DestroyString(ME_String *s);
void ME_AppendString(ME_String *s1, const ME_String *s2); void ME_AppendString(ME_String *s1, const ME_String *s2);
ME_String *ME_ConcatString(const ME_String *s1, const ME_String *s2);
ME_String *ME_VSplitString(ME_String *orig, int nVPos); ME_String *ME_VSplitString(ME_String *orig, int nVPos);
int ME_IsWhitespaces(const ME_String *s); int ME_IsWhitespaces(const ME_String *s);
int ME_IsSplitable(const ME_String *s); int ME_IsSplitable(const ME_String *s);
/* int ME_CalcSkipChars(ME_String *s); */
int ME_StrLen(const ME_String *s);
int ME_StrVLen(const ME_String *s);
int ME_FindNonWhitespaceV(const ME_String *s, int nVChar); int ME_FindNonWhitespaceV(const ME_String *s, int nVChar);
int ME_FindWhitespaceV(ME_String *s, int nVChar); int ME_FindWhitespaceV(ME_String *s, int nVChar);
int ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code); int ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code);
int ME_GetCharFwd(const ME_String *s, int nPos); /* get char starting from start */
int ME_GetCharBack(const ME_String *s, int nPos); /* get char starting from \0 */
int ME_StrRelPos(const ME_String *s, int nVChar, int *pRelChars);
int ME_StrRelPos2(const ME_String *s, int nVChar, int nRelChars);
int ME_VPosToPos(ME_String *s, int nVPos);
int ME_PosToVPos(const ME_String *s, int nPos);
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars); void ME_StrDeleteV(ME_String *s, int nVChar, int nChars);
/* smart helpers for A<->W conversions, they reserve/free memory and call MultiByte<->WideChar functions */ /* smart helpers for A<->W conversions, they reserve/free memory and call MultiByte<->WideChar functions */
LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz); LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz);
@ -132,7 +119,6 @@ int ME_ReverseFindNonWhitespaceV(const ME_String *s, int nVChar);
int ME_ReverseFindWhitespaceV(const ME_String *s, int nVChar); int ME_ReverseFindWhitespaceV(const ME_String *s, int nVChar);
/* row.c */ /* row.c */
ME_DisplayItem *ME_FindRowStart(ME_Context *c, ME_DisplayItem *run, int nRelPos);
ME_DisplayItem *ME_RowStart(ME_DisplayItem *item); ME_DisplayItem *ME_RowStart(ME_DisplayItem *item);
/* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); */ /* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); */
void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */ void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */
@ -162,8 +148,8 @@ ME_DisplayItem *ME_SplitFurther(ME_TextEditor *editor, ME_DisplayItem *run);
void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run); void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run);
SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx); SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx);
void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor); void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor);
void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs); void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppPara, ME_DisplayItem **ppRun, int *pOfs);
int ME_CharOfsFromRunOfs(ME_TextEditor *editor, ME_DisplayItem *pRun, int nOfs); 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_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift);
void ME_SetCharFormat(ME_TextEditor *editor, int nFrom, int nLen, CHARFORMAT2W *pFmt); void ME_SetCharFormat(ME_TextEditor *editor, int nFrom, int nLen, CHARFORMAT2W *pFmt);
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt); void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt);
@ -211,7 +197,7 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor);
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force); void ME_SendRequestResize(ME_TextEditor *editor, BOOL force);
/* para.c */ /* para.c */
ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run); ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run);
void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end); void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end);
void ME_MakeFirstParagraph(ME_TextEditor *editor); void ME_MakeFirstParagraph(ME_TextEditor *editor);
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, ME_String *eol_str, int paraFlags); ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, ME_String *eol_str, int paraFlags);

View file

@ -164,12 +164,6 @@ typedef struct tagME_Run
REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */ REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */
} ME_Run; } ME_Run;
typedef struct tagME_Document {
struct tagME_DisplayItem *def_char_style;
struct tagME_DisplayItem *def_para_style;
int last_wrapped_line;
} ME_Document;
typedef struct tagME_Border typedef struct tagME_Border
{ {
int width; int width;
@ -197,7 +191,7 @@ typedef struct tagME_Paragraph
int nHeight, nWidth; int nHeight, nWidth;
int nLastPaintYPos, nLastPaintHeight; int nLastPaintYPos, nLastPaintHeight;
int nRows; int nRows;
struct tagME_DisplayItem *prev_para, *next_para, *document; struct tagME_DisplayItem *prev_para, *next_para;
} ME_Paragraph; } ME_Paragraph;
typedef struct tagME_Cell /* v4.1 */ typedef struct tagME_Cell /* v4.1 */
@ -242,7 +236,6 @@ typedef struct tagME_DisplayItem
ME_Row row; ME_Row row;
ME_Cell cell; ME_Cell cell;
ME_Paragraph para; ME_Paragraph para;
ME_Document doc; /* not used */
ME_Style *ustyle; /* used by diUndoSetCharFormat */ ME_Style *ustyle; /* used by diUndoSetCharFormat */
} member; } member;
} ME_DisplayItem; } ME_DisplayItem;
@ -263,6 +256,7 @@ typedef struct tagME_TextBuffer
typedef struct tagME_Cursor typedef struct tagME_Cursor
{ {
ME_DisplayItem *pPara;
ME_DisplayItem *pRun; ME_DisplayItem *pRun;
int nOffset; int nOffset;
} ME_Cursor; } ME_Cursor;
@ -342,6 +336,7 @@ typedef struct tagME_TextEditor
SIZE sizeWindow; SIZE sizeWindow;
int nTotalLength, nLastTotalLength; int nTotalLength, nLastTotalLength;
int nTotalWidth, nLastTotalWidth; int nTotalWidth, nLastTotalWidth;
int nAvailWidth; /* 0 = wrap to client area, else wrap width in twips */
int nUDArrowX; int nUDArrowX;
int nSequence; int nSequence;
COLORREF rgbBackColor; COLORREF rgbBackColor;
@ -396,6 +391,7 @@ typedef struct tagME_Context
RECT rcView; RECT rcView;
HBRUSH hbrMargin; HBRUSH hbrMargin;
SIZE dpi; SIZE dpi;
int nAvailWidth;
/* those are valid inside ME_WrapTextParagraph and related */ /* those are valid inside ME_WrapTextParagraph and related */
POINT ptFirstRun; POINT ptFirstRun;
@ -412,10 +408,11 @@ typedef struct tagME_WrapContext
int nRow; int nRow;
POINT pt; POINT pt;
BOOL bOverflown, bWordWrap; BOOL bOverflown, bWordWrap;
ME_DisplayItem *pPara;
ME_DisplayItem *pRowStart; ME_DisplayItem *pRowStart;
ME_DisplayItem *pLastSplittableRun; ME_DisplayItem *pLastSplittableRun;
POINT ptLastSplittableRun; POINT ptLastSplittableRun;
} ME_WrapContext; } ME_WrapContext;
#endif #endif

View file

@ -98,16 +98,6 @@ ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass)
return NULL; return NULL;
} }
ME_DisplayItem *ME_FindItemFwdOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass)
{
while(di!=NULL) {
if (ME_DITypesEqual(di->type, nTypeOrClass))
return di;
di = di->next;
}
return NULL;
}
void ME_DestroyDisplayItem(ME_DisplayItem *item) { void ME_DestroyDisplayItem(ME_DisplayItem *item) {
/* TRACE("type=%s\n", ME_GetDITypeName(item->type)); */ /* TRACE("type=%s\n", ME_GetDITypeName(item->type)); */
if (item->type==diParagraph || item->type == diUndoSetParagraphFormat) { if (item->type==diParagraph || item->type == diUndoSetParagraphFormat) {

View file

@ -44,7 +44,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
editor->nSequence++; editor->nSequence++;
ME_InitContext(&c, editor, hDC); ME_InitContext(&c, editor, hDC);
SetBkMode(hDC, TRANSPARENT); SetBkMode(hDC, TRANSPARENT);
ME_MoveCaret(editor); /* Calls ME_WrapMarkedParagraphs */ ME_MoveCaret(editor);
item = editor->pBuffer->pFirst->next; item = editor->pBuffer->pFirst->next;
/* This context point is an offset for the paragraph positions stored /* This context point is an offset for the paragraph positions stored
* during wrapping. It shouldn't be modified during painting. */ * during wrapping. It shouldn't be modified during painting. */
@ -137,7 +137,6 @@ void ME_Repaint(ME_TextEditor *editor)
void ME_UpdateRepaint(ME_TextEditor *editor) void ME_UpdateRepaint(ME_TextEditor *editor)
{ {
/* Should be called whenever the contents of the control have changed */ /* Should be called whenever the contents of the control have changed */
ME_Cursor *pCursor;
BOOL wrappedParagraphs; BOOL wrappedParagraphs;
wrappedParagraphs = ME_WrapMarkedParagraphs(editor); wrappedParagraphs = ME_WrapMarkedParagraphs(editor);
@ -145,8 +144,7 @@ void ME_UpdateRepaint(ME_TextEditor *editor)
ME_UpdateScrollBar(editor); ME_UpdateScrollBar(editor);
/* Ensure that the cursor is visible */ /* Ensure that the cursor is visible */
pCursor = &editor->pCursors[0]; ME_EnsureVisible(editor, &editor->pCursors[0]);
ME_EnsureVisible(editor, pCursor);
/* send EN_CHANGE if the event mask asks for it */ /* send EN_CHANGE if the event mask asks for it */
if(editor->nEventMask & ENM_CHANGE) if(editor->nEventMask & ENM_CHANGE)
@ -446,9 +444,9 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
{ {
if (c->editor->cPasswordMask) if (c->editor->cPasswordMask)
{ {
ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText)); ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask, run->strText->nLen);
ME_DrawTextWithStyle(c, x, y, ME_DrawTextWithStyle(c, x, y,
szMasked->szData, ME_StrVLen(szMasked), run->style, run->nWidth, szMasked->szData, szMasked->nLen, run->style, run->nWidth,
nSelFrom-runofs,nSelTo-runofs, nSelFrom-runofs,nSelTo-runofs,
c->pt.y + para->pt.y + start->member.row.pt.y, c->pt.y + para->pt.y + start->member.row.pt.y,
start->member.row.nHeight); start->member.row.nHeight);
@ -456,7 +454,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
} }
else else
ME_DrawTextWithStyle(c, x, y, ME_DrawTextWithStyle(c, x, y,
run->strText->szData, ME_StrVLen(run->strText), run->style, run->nWidth, run->strText->szData, run->strText->nLen, run->style, run->nWidth,
nSelFrom-runofs,nSelTo-runofs, nSelFrom-runofs,nSelTo-runofs,
c->pt.y + para->pt.y + start->member.row.pt.y, c->pt.y + para->pt.y + start->member.row.pt.y,
start->member.row.nHeight); start->member.row.nHeight);
@ -1073,7 +1071,8 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0; bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
&& (editor->styleFlags & WS_VSCROLL)) && (editor->styleFlags & WS_VSCROLL)
&& (editor->styleFlags & ES_MULTILINE))
|| (editor->styleFlags & ES_DISABLENOSCROLL); || (editor->styleFlags & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible) if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
@ -1112,6 +1111,18 @@ void ME_ScrollRight(ME_TextEditor *editor, int cx)
ME_HScrollAbs(editor, editor->horz_si.nPos + cx); ME_HScrollAbs(editor, editor->horz_si.nPos + cx);
} }
/* Calculates the visiblity after a call to SetScrollRange or
* SetScrollInfo with SIF_RANGE. */
static BOOL ME_PostSetScrollRangeVisibility(SCROLLINFO *si)
{
if (si->fMask & SIF_DISABLENOSCROLL)
return TRUE;
/* This must match the check in SetScrollInfo to determine whether
* to show or hide the scrollbars. */
return si->nMin < si->nMax - max(si->nPage - 1, 0);
}
void ME_UpdateScrollBar(ME_TextEditor *editor) void ME_UpdateScrollBar(ME_TextEditor *editor)
{ {
/* Note that this is the only function that should ever call /* Note that this is the only function that should ever call
@ -1159,15 +1170,14 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, si.nMin, si.nMax, FALSE); ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, si.nMin, si.nMax, FALSE);
ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, si.nPos, TRUE); ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, si.nPos, TRUE);
} }
/* SetScrollInfo or SetScrollRange change scrollbar visibility. */
bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si);
} }
} }
if (si.fMask & SIF_DISABLENOSCROLL) { if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE; bScrollBarWillBeVisible = TRUE;
} else if (!(editor->styleFlags & WS_HSCROLL)) { } else if (!(editor->styleFlags & WS_HSCROLL)) {
/* SetScrollInfo or SetScrollRange may cause the scrollbar to be
* shown, so hide the scrollbar if necessary. */
bScrollBarWasVisible = bScrollBarWillBeVisible;
bScrollBarWillBeVisible = FALSE; bScrollBarWillBeVisible = FALSE;
} }
@ -1176,7 +1186,8 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
/* Update vertical scrollbar */ /* Update vertical scrollbar */
bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage; bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage;
bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy; bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy &&
(editor->styleFlags & ES_MULTILINE);
if (editor->vert_si.nPos && !bScrollBarWillBeVisible) if (editor->vert_si.nPos && !bScrollBarWillBeVisible)
{ {
@ -1205,15 +1216,14 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, si.nMin, si.nMax, FALSE); ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, si.nMin, si.nMax, FALSE);
ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, si.nPos, TRUE); ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, si.nPos, TRUE);
} }
/* SetScrollInfo or SetScrollRange change scrollbar visibility. */
bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si);
} }
} }
if (si.fMask & SIF_DISABLENOSCROLL) { if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE; bScrollBarWillBeVisible = TRUE;
} else if (!(editor->styleFlags & WS_VSCROLL)) { } else if (!(editor->styleFlags & WS_VSCROLL)) {
/* SetScrollInfo or SetScrollRange may cause the scrollbar to be
* shown, so hide the scrollbar if necessary. */
bScrollBarWasVisible = bScrollBarWillBeVisible;
bScrollBarWillBeVisible = FALSE; bScrollBarWillBeVisible = FALSE;
} }
@ -1226,7 +1236,7 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_Run *pRun = &pCursor->pRun->member.run; ME_Run *pRun = &pCursor->pRun->member.run;
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
ME_DisplayItem *pPara = ME_FindItemBack(pCursor->pRun, diParagraph); ME_DisplayItem *pPara = pCursor->pPara;
int x, y, yheight; int x, y, yheight;
assert(pRow); assert(pRow);
@ -1267,26 +1277,24 @@ ME_InvalidateSelection(ME_TextEditor *editor)
assert(para1->type == diParagraph); assert(para1->type == diParagraph);
assert(para2->type == diParagraph); assert(para2->type == diParagraph);
/* last selection markers aren't always updated, which means /* last selection markers aren't always updated, which means
they can point past the end of the document */ * they can point past the end of the document */
if (editor->nLastSelStart > len || editor->nLastSelEnd > len) { if (editor->nLastSelStart > len || editor->nLastSelEnd > len) {
ME_MarkForPainting(editor, ME_MarkForPainting(editor,
ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph), ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph),
ME_FindItemFwd(editor->pBuffer->pFirst, diTextEnd)); editor->pBuffer->pLast);
} else { } else {
/* if the start part of selection is being expanded or contracted... */ /* if the start part of selection is being expanded or contracted... */
if (nStart < editor->nLastSelStart) { if (nStart < editor->nLastSelStart) {
ME_MarkForPainting(editor, para1, ME_FindItemFwd(editor->pLastSelStartPara, diParagraphOrEnd)); ME_MarkForPainting(editor, para1, editor->pLastSelStartPara->member.para.next_para);
} else } else if (nStart > editor->nLastSelStart) {
if (nStart > editor->nLastSelStart) { ME_MarkForPainting(editor, editor->pLastSelStartPara, para1->member.para.next_para);
ME_MarkForPainting(editor, editor->pLastSelStartPara, ME_FindItemFwd(para1, diParagraphOrEnd));
} }
/* if the end part of selection is being contracted or expanded... */ /* if the end part of selection is being contracted or expanded... */
if (nEnd < editor->nLastSelEnd) { if (nEnd < editor->nLastSelEnd) {
ME_MarkForPainting(editor, para2, ME_FindItemFwd(editor->pLastSelEndPara, diParagraphOrEnd)); ME_MarkForPainting(editor, para2, editor->pLastSelEndPara->member.para.next_para);
} else } else if (nEnd > editor->nLastSelEnd) {
if (nEnd > editor->nLastSelEnd) { ME_MarkForPainting(editor, editor->pLastSelEndPara, para2->member.para.next_para);
ME_MarkForPainting(editor, editor->pLastSelEndPara, ME_FindItemFwd(para2, diParagraphOrEnd));
} }
} }

View file

@ -208,7 +208,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run,
ME_DisplayItem *new_para = ME_MakeDI(diParagraph); ME_DisplayItem *new_para = ME_MakeDI(diParagraph);
ME_DisplayItem *end_run; ME_DisplayItem *end_run;
ME_UndoItem *undo = NULL; ME_UndoItem *undo = NULL;
int ofs; int ofs, i;
ME_DisplayItem *pp; ME_DisplayItem *pp;
int run_flags = MERF_ENDPARA; int run_flags = MERF_ENDPARA;
@ -236,14 +236,23 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run,
undo = ME_AddUndoItem(editor, diUndoJoinParagraphs, NULL); undo = ME_AddUndoItem(editor, diUndoJoinParagraphs, NULL);
if (undo) if (undo)
undo->nStart = run_para->member.para.nCharOfs + ofs; undo->nStart = run_para->member.para.nCharOfs + ofs;
/* Update selection cursors to point to the correct paragraph. */
for (i = 0; i < editor->nCursors; i++) {
if (editor->pCursors[i].pPara == run_para &&
run->member.run.nCharOfs <= editor->pCursors[i].pRun->member.run.nCharOfs)
{
editor->pCursors[i].pPara = new_para;
}
}
/* the new paragraph will have a different starting offset, so let's update its runs */ /* the new paragraph will have a different starting offset, so let's update its runs */
pp = run; pp = run;
while(pp->type == diRun) { while(pp->type == diRun) {
pp->member.run.nCharOfs -= ofs; pp->member.run.nCharOfs -= ofs;
pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd); pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd);
} }
new_para->member.para.nCharOfs = ME_GetParagraph(run)->member.para.nCharOfs+ofs; new_para->member.para.nCharOfs = run_para->member.para.nCharOfs + ofs;
new_para->member.para.nCharOfs += eol_str->nLen; new_para->member.para.nCharOfs += eol_str->nLen;
new_para->member.para.nFlags = MEPF_REWRAP; new_para->member.para.nFlags = MEPF_REWRAP;
@ -309,11 +318,11 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run,
/* force rewrap of the */ /* force rewrap of the */
run_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP; run_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP; new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
/* we've added the end run, so we need to modify nCharOfs in the next paragraphs */ /* we've added the end run, so we need to modify nCharOfs in the next paragraphs */
ME_PropagateCharOffset(next_para, eol_str->nLen); ME_PropagateCharOffset(next_para, eol_str->nLen);
editor->nParagraphs++; editor->nParagraphs++;
return new_para; return new_para;
} }
@ -330,9 +339,9 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
assert(tp->type == diParagraph); assert(tp->type == diParagraph);
assert(tp->member.para.next_para); assert(tp->member.para.next_para);
assert(tp->member.para.next_para->type == diParagraph); assert(tp->member.para.next_para->type == diParagraph);
pNext = tp->member.para.next_para; pNext = tp->member.para.next_para;
/* Need to locate end-of-paragraph run here, in order to know end_len */ /* Need to locate end-of-paragraph run here, in order to know end_len */
pRun = ME_FindItemBack(pNext, diRunOrParagraph); pRun = ME_FindItemBack(pNext, diRunOrParagraph);
@ -397,19 +406,21 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
pTmp = pTmp->next; pTmp = pTmp->next;
} }
} }
shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len; shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len;
pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph); pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph);
assert(pFirstRunInNext->type == diRun); assert(pFirstRunInNext->type == diRun);
/* if some cursor points at end of paragraph, make it point to the first /* Update selection cursors so they don't point to the removed end
run of the next joined paragraph */ * paragraph run, and point to the correct paragraph. */
for (i=0; i<editor->nCursors; i++) { for (i=0; i < editor->nCursors; i++) {
if (editor->pCursors[i].pRun == pRun) { if (editor->pCursors[i].pRun == pRun) {
editor->pCursors[i].pRun = pFirstRunInNext; editor->pCursors[i].pRun = pFirstRunInNext;
editor->pCursors[i].nOffset = 0; editor->pCursors[i].nOffset = 0;
} else if (editor->pCursors[i].pPara == pNext) {
editor->pCursors[i].pPara = tp;
} }
} }
@ -421,7 +432,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
TRACE("shifting \"%s\" by %d (previous %d)\n", debugstr_w(pTmp->member.run.strText->szData), shift, pTmp->member.run.nCharOfs); TRACE("shifting \"%s\" by %d (previous %d)\n", debugstr_w(pTmp->member.run.strText->szData), shift, pTmp->member.run.nCharOfs);
pTmp->member.run.nCharOfs += shift; pTmp->member.run.nCharOfs += shift;
} while(1); } while(1);
ME_Remove(pRun); ME_Remove(pRun);
ME_DestroyDisplayItem(pRun); ME_DestroyDisplayItem(pRun);
@ -429,16 +440,16 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
editor->pLastSelStartPara = tp; editor->pLastSelStartPara = tp;
if (editor->pLastSelEndPara == pNext) if (editor->pLastSelEndPara == pNext)
editor->pLastSelEndPara = tp; editor->pLastSelEndPara = tp;
tp->member.para.next_para = pNext->member.para.next_para; tp->member.para.next_para = pNext->member.para.next_para;
pNext->member.para.next_para->member.para.prev_para = tp; pNext->member.para.next_para->member.para.prev_para = tp;
ME_Remove(pNext); ME_Remove(pNext);
ME_DestroyDisplayItem(pNext); ME_DestroyDisplayItem(pNext);
ME_PropagateCharOffset(tp->member.para.next_para, -end_len); ME_PropagateCharOffset(tp->member.para.next_para, -end_len);
ME_CheckCharOffsets(editor); ME_CheckCharOffsets(editor);
editor->nParagraphs--; editor->nParagraphs--;
tp->member.para.nFlags |= MEPF_REWRAP; tp->member.para.nFlags |= MEPF_REWRAP;
return tp; return tp;
@ -515,9 +526,12 @@ void
ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end) ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end)
{ {
ME_Cursor *pEndCursor = &editor->pCursors[1]; ME_Cursor *pEndCursor = &editor->pCursors[1];
*para = ME_GetParagraph(editor->pCursors[0].pRun); *para = editor->pCursors[0].pPara;
*para_end = ME_GetParagraph(editor->pCursors[1].pRun); *para_end = editor->pCursors[1].pPara;
if (*para == *para_end)
return;
if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) { if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) {
ME_DisplayItem *tmp = *para; ME_DisplayItem *tmp = *para;
@ -525,22 +539,20 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte
*para_end = tmp; *para_end = tmp;
pEndCursor = &editor->pCursors[0]; pEndCursor = &editor->pCursors[0];
} }
/* selection consists of chars from nFrom up to nTo-1 */ /* The paragraph at the end of a non-empty selection isn't included
if ((*para_end)->member.para.nCharOfs > (*para)->member.para.nCharOfs) { * if the selection ends at the start of the paragraph. */
if (!pEndCursor->nOffset) { if (!pEndCursor->pRun->member.run.nCharOfs && !pEndCursor->nOffset)
*para_end = ME_GetParagraph(ME_FindItemBack(pEndCursor->pRun, diRun)); *para_end = (*para_end)->member.para.prev_para;
}
}
} }
BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt)
{ {
ME_DisplayItem *para, *para_end; ME_DisplayItem *para, *para_end;
ME_GetSelectionParas(editor, &para, &para_end); ME_GetSelectionParas(editor, &para, &para_end);
do { do {
ME_SetParaFormat(editor, para, pFmt); ME_SetParaFormat(editor, para, pFmt);
if (para == para_end) if (para == para_end)

View file

@ -475,6 +475,11 @@ static void RTFUngetToken(RTF_Info *info)
info->pushedMinor = info->rtfMinor; info->pushedMinor = info->rtfMinor;
info->pushedParam = info->rtfParam; info->pushedParam = info->rtfParam;
lstrcpyA (info->pushedTextBuf, info->rtfTextBuf); lstrcpyA (info->pushedTextBuf, info->rtfTextBuf);
/* The read hook decrements stackTop on rtfEndGroup, so
* increment the value to compensate for it being decremented
* twice due to the RTFUngetToken. */
if(RTFCheckCM (info, rtfGroup, rtfEndGroup))
info->stackTop++;
} }

View file

@ -524,7 +524,7 @@ ITextDocument_fnGetSelection(ITextDocument* me, ITextSelection** ppSel)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnGetStoryCount(ITextDocument* me, long* pCount) ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -541,7 +541,7 @@ ITextDocument_fnGetStoryRanges(ITextDocument* me,
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnGetSaved(ITextDocument* me, long* pValue) ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -549,7 +549,7 @@ ITextDocument_fnGetSaved(ITextDocument* me, long* pValue)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnSetSaved(ITextDocument* me, long Value) ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -581,8 +581,8 @@ ITextDocument_fnNew(ITextDocument* me)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, long Flags, ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
long CodePage) LONG CodePage)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -590,8 +590,8 @@ ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, long Flags,
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, long Flags, ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
long CodePage) LONG CodePage)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -599,7 +599,7 @@ ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, long Flags,
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnFreeze(ITextDocument* me, long* pCount) ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -607,7 +607,7 @@ ITextDocument_fnFreeze(ITextDocument* me, long* pCount)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnUnfreeze(ITextDocument* me, long* pCount) ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -631,7 +631,7 @@ ITextDocument_fnEndEditCollection(ITextDocument* me)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnUndo(ITextDocument* me, long Count, long* prop) ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -639,7 +639,7 @@ ITextDocument_fnUndo(ITextDocument* me, long Count, long* prop)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnRedo(ITextDocument* me, long Count, long* prop) ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
FIXME("stub %p\n",This); FIXME("stub %p\n",This);
@ -647,7 +647,7 @@ ITextDocument_fnRedo(ITextDocument* me, long Count, long* prop)
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnRange(ITextDocument* me, long cp1, long cp2, ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
ITextRange** ppRange) ITextRange** ppRange)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
@ -656,7 +656,7 @@ ITextDocument_fnRange(ITextDocument* me, long cp1, long cp2,
} }
static HRESULT WINAPI static HRESULT WINAPI
ITextDocument_fnRangeFromPoint(ITextDocument* me, long x, long y, ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
ITextRange** ppRange) ITextRange** ppRange)
{ {
IRichEditOleImpl *This = impl_from_ITextDocument(me); IRichEditOleImpl *This = impl_from_ITextDocument(me);
@ -813,7 +813,7 @@ static HRESULT WINAPI ITextSelection_fnSetText(
static HRESULT WINAPI ITextSelection_fnGetChar( static HRESULT WINAPI ITextSelection_fnGetChar(
ITextSelection *me, ITextSelection *me,
long *pch) LONG *pch)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -825,7 +825,7 @@ static HRESULT WINAPI ITextSelection_fnGetChar(
static HRESULT WINAPI ITextSelection_fnSetChar( static HRESULT WINAPI ITextSelection_fnSetChar(
ITextSelection *me, ITextSelection *me,
long ch) LONG ch)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -873,7 +873,7 @@ static HRESULT WINAPI ITextSelection_fnSetFormattedText(
static HRESULT WINAPI ITextSelection_fnGetStart( static HRESULT WINAPI ITextSelection_fnGetStart(
ITextSelection *me, ITextSelection *me,
long *pcpFirst) LONG *pcpFirst)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -885,7 +885,7 @@ static HRESULT WINAPI ITextSelection_fnGetStart(
static HRESULT WINAPI ITextSelection_fnSetStart( static HRESULT WINAPI ITextSelection_fnSetStart(
ITextSelection *me, ITextSelection *me,
long cpFirst) LONG cpFirst)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -897,7 +897,7 @@ static HRESULT WINAPI ITextSelection_fnSetStart(
static HRESULT WINAPI ITextSelection_fnGetEnd( static HRESULT WINAPI ITextSelection_fnGetEnd(
ITextSelection *me, ITextSelection *me,
long *pcpLim) LONG *pcpLim)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -909,7 +909,7 @@ static HRESULT WINAPI ITextSelection_fnGetEnd(
static HRESULT WINAPI ITextSelection_fnSetEnd( static HRESULT WINAPI ITextSelection_fnSetEnd(
ITextSelection *me, ITextSelection *me,
long cpLim) LONG cpLim)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -969,7 +969,7 @@ static HRESULT WINAPI ITextSelection_fnSetPara(
static HRESULT WINAPI ITextSelection_fnGetStoryLength( static HRESULT WINAPI ITextSelection_fnGetStoryLength(
ITextSelection *me, ITextSelection *me,
long *pcch) LONG *pcch)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -981,7 +981,7 @@ static HRESULT WINAPI ITextSelection_fnGetStoryLength(
static HRESULT WINAPI ITextSelection_fnGetStoryType( static HRESULT WINAPI ITextSelection_fnGetStoryType(
ITextSelection *me, ITextSelection *me,
long *pValue) LONG *pValue)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -993,7 +993,7 @@ static HRESULT WINAPI ITextSelection_fnGetStoryType(
static HRESULT WINAPI ITextSelection_fnCollapse( static HRESULT WINAPI ITextSelection_fnCollapse(
ITextSelection *me, ITextSelection *me,
long bStart) LONG bStart)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1005,8 +1005,8 @@ static HRESULT WINAPI ITextSelection_fnCollapse(
static HRESULT WINAPI ITextSelection_fnExpand( static HRESULT WINAPI ITextSelection_fnExpand(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1018,8 +1018,8 @@ static HRESULT WINAPI ITextSelection_fnExpand(
static HRESULT WINAPI ITextSelection_fnGetIndex( static HRESULT WINAPI ITextSelection_fnGetIndex(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long *pIndex) LONG *pIndex)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1031,9 +1031,9 @@ static HRESULT WINAPI ITextSelection_fnGetIndex(
static HRESULT WINAPI ITextSelection_fnSetIndex( static HRESULT WINAPI ITextSelection_fnSetIndex(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Index, LONG Index,
long Extend) LONG Extend)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1045,8 +1045,8 @@ static HRESULT WINAPI ITextSelection_fnSetIndex(
static HRESULT WINAPI ITextSelection_fnSetRange( static HRESULT WINAPI ITextSelection_fnSetRange(
ITextSelection *me, ITextSelection *me,
long cpActive, LONG cpActive,
long cpOther) LONG cpOther)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1059,7 +1059,7 @@ static HRESULT WINAPI ITextSelection_fnSetRange(
static HRESULT WINAPI ITextSelection_fnInRange( static HRESULT WINAPI ITextSelection_fnInRange(
ITextSelection *me, ITextSelection *me,
ITextRange *pRange, ITextRange *pRange,
long *pb) LONG *pb)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1072,7 +1072,7 @@ static HRESULT WINAPI ITextSelection_fnInRange(
static HRESULT WINAPI ITextSelection_fnInStory( static HRESULT WINAPI ITextSelection_fnInStory(
ITextSelection *me, ITextSelection *me,
ITextRange *pRange, ITextRange *pRange,
long *pb) LONG *pb)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1085,7 +1085,7 @@ static HRESULT WINAPI ITextSelection_fnInStory(
static HRESULT WINAPI ITextSelection_fnIsEqual( static HRESULT WINAPI ITextSelection_fnIsEqual(
ITextSelection *me, ITextSelection *me,
ITextRange *pRange, ITextRange *pRange,
long *pb) LONG *pb)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1108,9 +1108,9 @@ static HRESULT WINAPI ITextSelection_fnSelect(
static HRESULT WINAPI ITextSelection_fnStartOf( static HRESULT WINAPI ITextSelection_fnStartOf(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1122,9 +1122,9 @@ static HRESULT WINAPI ITextSelection_fnStartOf(
static HRESULT WINAPI ITextSelection_fnEndOf( static HRESULT WINAPI ITextSelection_fnEndOf(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1136,9 +1136,9 @@ static HRESULT WINAPI ITextSelection_fnEndOf(
static HRESULT WINAPI ITextSelection_fnMove( static HRESULT WINAPI ITextSelection_fnMove(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1150,9 +1150,9 @@ static HRESULT WINAPI ITextSelection_fnMove(
static HRESULT WINAPI ITextSelection_fnMoveStart( static HRESULT WINAPI ITextSelection_fnMoveStart(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1164,9 +1164,9 @@ static HRESULT WINAPI ITextSelection_fnMoveStart(
static HRESULT WINAPI ITextSelection_fnMoveEnd( static HRESULT WINAPI ITextSelection_fnMoveEnd(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1179,8 +1179,8 @@ static HRESULT WINAPI ITextSelection_fnMoveEnd(
static HRESULT WINAPI ITextSelection_fnMoveWhile( static HRESULT WINAPI ITextSelection_fnMoveWhile(
ITextSelection *me, ITextSelection *me,
VARIANT *Cset, VARIANT *Cset,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1193,8 +1193,8 @@ static HRESULT WINAPI ITextSelection_fnMoveWhile(
static HRESULT WINAPI ITextSelection_fnMoveStartWhile( static HRESULT WINAPI ITextSelection_fnMoveStartWhile(
ITextSelection *me, ITextSelection *me,
VARIANT *Cset, VARIANT *Cset,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1207,8 +1207,8 @@ static HRESULT WINAPI ITextSelection_fnMoveStartWhile(
static HRESULT WINAPI ITextSelection_fnMoveEndWhile( static HRESULT WINAPI ITextSelection_fnMoveEndWhile(
ITextSelection *me, ITextSelection *me,
VARIANT *Cset, VARIANT *Cset,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1221,8 +1221,8 @@ static HRESULT WINAPI ITextSelection_fnMoveEndWhile(
static HRESULT WINAPI ITextSelection_fnMoveUntil( static HRESULT WINAPI ITextSelection_fnMoveUntil(
ITextSelection *me, ITextSelection *me,
VARIANT *Cset, VARIANT *Cset,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1235,8 +1235,8 @@ static HRESULT WINAPI ITextSelection_fnMoveUntil(
static HRESULT WINAPI ITextSelection_fnMoveStartUntil( static HRESULT WINAPI ITextSelection_fnMoveStartUntil(
ITextSelection *me, ITextSelection *me,
VARIANT *Cset, VARIANT *Cset,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1249,8 +1249,8 @@ static HRESULT WINAPI ITextSelection_fnMoveStartUntil(
static HRESULT WINAPI ITextSelection_fnMoveEndUntil( static HRESULT WINAPI ITextSelection_fnMoveEndUntil(
ITextSelection *me, ITextSelection *me,
VARIANT *Cset, VARIANT *Cset,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1263,9 +1263,9 @@ static HRESULT WINAPI ITextSelection_fnMoveEndUntil(
static HRESULT WINAPI ITextSelection_fnFindText( static HRESULT WINAPI ITextSelection_fnFindText(
ITextSelection *me, ITextSelection *me,
BSTR bstr, BSTR bstr,
long cch, LONG cch,
long Flags, LONG Flags,
long *pLength) LONG *pLength)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1278,9 +1278,9 @@ static HRESULT WINAPI ITextSelection_fnFindText(
static HRESULT WINAPI ITextSelection_fnFindTextStart( static HRESULT WINAPI ITextSelection_fnFindTextStart(
ITextSelection *me, ITextSelection *me,
BSTR bstr, BSTR bstr,
long cch, LONG cch,
long Flags, LONG Flags,
long *pLength) LONG *pLength)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1293,9 +1293,9 @@ static HRESULT WINAPI ITextSelection_fnFindTextStart(
static HRESULT WINAPI ITextSelection_fnFindTextEnd( static HRESULT WINAPI ITextSelection_fnFindTextEnd(
ITextSelection *me, ITextSelection *me,
BSTR bstr, BSTR bstr,
long cch, LONG cch,
long Flags, LONG Flags,
long *pLength) LONG *pLength)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1307,9 +1307,9 @@ static HRESULT WINAPI ITextSelection_fnFindTextEnd(
static HRESULT WINAPI ITextSelection_fnDelete( static HRESULT WINAPI ITextSelection_fnDelete(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1346,7 +1346,7 @@ static HRESULT WINAPI ITextSelection_fnCopy(
static HRESULT WINAPI ITextSelection_fnPaste( static HRESULT WINAPI ITextSelection_fnPaste(
ITextSelection *me, ITextSelection *me,
VARIANT *pVar, VARIANT *pVar,
long Format) LONG Format)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1359,8 +1359,8 @@ static HRESULT WINAPI ITextSelection_fnPaste(
static HRESULT WINAPI ITextSelection_fnCanPaste( static HRESULT WINAPI ITextSelection_fnCanPaste(
ITextSelection *me, ITextSelection *me,
VARIANT *pVar, VARIANT *pVar,
long Format, LONG Format,
long *pb) LONG *pb)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1372,7 +1372,7 @@ static HRESULT WINAPI ITextSelection_fnCanPaste(
static HRESULT WINAPI ITextSelection_fnCanEdit( static HRESULT WINAPI ITextSelection_fnCanEdit(
ITextSelection *me, ITextSelection *me,
long *pb) LONG *pb)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1384,7 +1384,7 @@ static HRESULT WINAPI ITextSelection_fnCanEdit(
static HRESULT WINAPI ITextSelection_fnChangeCase( static HRESULT WINAPI ITextSelection_fnChangeCase(
ITextSelection *me, ITextSelection *me,
long Type) LONG Type)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1396,9 +1396,9 @@ static HRESULT WINAPI ITextSelection_fnChangeCase(
static HRESULT WINAPI ITextSelection_fnGetPoint( static HRESULT WINAPI ITextSelection_fnGetPoint(
ITextSelection *me, ITextSelection *me,
long Type, LONG Type,
long *cx, LONG *cx,
long *cy) LONG *cy)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1410,10 +1410,10 @@ static HRESULT WINAPI ITextSelection_fnGetPoint(
static HRESULT WINAPI ITextSelection_fnSetPoint( static HRESULT WINAPI ITextSelection_fnSetPoint(
ITextSelection *me, ITextSelection *me,
long x, LONG x,
long y, LONG y,
long Type, LONG Type,
long Extend) LONG Extend)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1425,7 +1425,7 @@ static HRESULT WINAPI ITextSelection_fnSetPoint(
static HRESULT WINAPI ITextSelection_fnScrollIntoView( static HRESULT WINAPI ITextSelection_fnScrollIntoView(
ITextSelection *me, ITextSelection *me,
long Value) LONG Value)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1450,7 +1450,7 @@ static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(
/*** ITextSelection methods ***/ /*** ITextSelection methods ***/
static HRESULT WINAPI ITextSelection_fnGetFlags( static HRESULT WINAPI ITextSelection_fnGetFlags(
ITextSelection *me, ITextSelection *me,
long *pFlags) LONG *pFlags)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1462,7 +1462,7 @@ static HRESULT WINAPI ITextSelection_fnGetFlags(
static HRESULT WINAPI ITextSelection_fnSetFlags( static HRESULT WINAPI ITextSelection_fnSetFlags(
ITextSelection *me, ITextSelection *me,
long Flags) LONG Flags)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1474,7 +1474,7 @@ static HRESULT WINAPI ITextSelection_fnSetFlags(
static HRESULT WINAPI ITextSelection_fnGetType( static HRESULT WINAPI ITextSelection_fnGetType(
ITextSelection *me, ITextSelection *me,
long *pType) LONG *pType)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1486,10 +1486,10 @@ static HRESULT WINAPI ITextSelection_fnGetType(
static HRESULT WINAPI ITextSelection_fnMoveLeft( static HRESULT WINAPI ITextSelection_fnMoveLeft(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1501,10 +1501,10 @@ static HRESULT WINAPI ITextSelection_fnMoveLeft(
static HRESULT WINAPI ITextSelection_fnMoveRight( static HRESULT WINAPI ITextSelection_fnMoveRight(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1516,10 +1516,10 @@ static HRESULT WINAPI ITextSelection_fnMoveRight(
static HRESULT WINAPI ITextSelection_fnMoveUp( static HRESULT WINAPI ITextSelection_fnMoveUp(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1531,10 +1531,10 @@ static HRESULT WINAPI ITextSelection_fnMoveUp(
static HRESULT WINAPI ITextSelection_fnMoveDown( static HRESULT WINAPI ITextSelection_fnMoveDown(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Count, LONG Count,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1546,9 +1546,9 @@ static HRESULT WINAPI ITextSelection_fnMoveDown(
static HRESULT WINAPI ITextSelection_fnHomeKey( static HRESULT WINAPI ITextSelection_fnHomeKey(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)
@ -1560,9 +1560,9 @@ static HRESULT WINAPI ITextSelection_fnHomeKey(
static HRESULT WINAPI ITextSelection_fnEndKey( static HRESULT WINAPI ITextSelection_fnEndKey(
ITextSelection *me, ITextSelection *me,
long Unit, LONG Unit,
long Extend, LONG Extend,
long *pDelta) LONG *pDelta)
{ {
ITextSelectionImpl *This = (ITextSelectionImpl *) me; ITextSelectionImpl *This = (ITextSelectionImpl *) me;
if (!This->reOle) if (!This->reOle)

View file

@ -24,50 +24,6 @@
#include "editor.h" #include "editor.h"
ME_DisplayItem *ME_FindRowStart(ME_Context *c, ME_DisplayItem *item,
int nRelPos) {
ME_DisplayItem *para = ME_GetParagraph(item);
ME_MustBeWrapped(c, para);
if(nRelPos<=0) { /* if this or preceding row */
do {
ME_DisplayItem *item2 = ME_FindItemBack(item, diStartRowOrParagraph);
if (item2->type == diParagraph)
{
if (item2->member.para.prev_para == NULL)
return item;
/* if skipping to the preceding paragraph, ensure it's wrapped */
ME_MustBeWrapped(c, item2->member.para.prev_para);
item = item2;
continue;
}
else if (item2->type == diStartRow)
{
nRelPos++;
if (nRelPos>0)
return item;
item = item2;
continue;
}
assert(0 == "bug in FindItemBack(item, diStartRowOrParagraph)");
item = item2;
} while(1);
}
while(nRelPos>0) { /* if one of the next rows */
ME_DisplayItem *item2 = ME_FindItemFwd(item, diStartRowOrParagraph);
if (!item2)
return item;
if (item2->type == diParagraph)
{
if (item2->member.para.next_para == NULL)
return item;
continue;
}
item = item2;
nRelPos--;
}
return item;
}
/* I'm sure these functions would simplify some code in caret ops etc, /* I'm sure these functions would simplify some code in caret ops etc,
* I just didn't remember them when I wrote that code * I just didn't remember them when I wrote that code
*/ */
@ -89,14 +45,15 @@ ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
{ {
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph); ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int nCount = 0; int nCount = 0;
while (item && nCount + item->member.para.nRows <= nRow) while (item->type == diParagraph &&
nCount + item->member.para.nRows <= nRow)
{ {
nCount += item->member.para.nRows; nCount += item->member.para.nRows;
item = ME_FindItemFwd(item, diParagraph); item = item->member.para.next_para;
} }
if (!item) if (item->type != diParagraph)
return item; return NULL;
for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++) for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++)
item = ME_FindItemFwd(item, diStartRow); item = ME_FindItemFwd(item, diStartRow);
return item; return item;
@ -106,18 +63,19 @@ ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
int int
ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs) ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs)
{ {
ME_DisplayItem *item = editor->pBuffer->pFirst->next; ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int nRow = 0; int nRow = 0;
while (item && item->member.para.next_para->member.para.nCharOfs <= nOfs) while (item->type == diParagraph &&
item->member.para.next_para->member.para.nCharOfs <= nOfs)
{ {
nRow += item->member.para.nRows; nRow += item->member.para.nRows;
item = ME_FindItemFwd(item, diParagraph); item = item->member.para.next_para;
} }
if (item) if (item->type == diParagraph)
{ {
ME_DisplayItem *next_para = item->member.para.next_para; ME_DisplayItem *next_para = item->member.para.next_para;
nOfs -= item->member.para.nCharOfs; nOfs -= item->member.para.nCharOfs;
item = ME_FindItemFwd(item, diRun); item = ME_FindItemFwd(item, diRun);
while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL) while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL)

View file

@ -141,35 +141,30 @@ void ME_CheckCharOffsets(ME_TextEditor *editor)
/****************************************************************************** /******************************************************************************
* ME_CharOfsFromRunOfs * ME_CharOfsFromRunOfs
* *
* Converts a character position relative to the start of the run, to a * Converts a character position relative to the start of the run, to a
* character position relative to the start of the document. * character position relative to the start of the document.
* Kind of a "local to global" offset conversion. * Kind of a "local to global" offset conversion.
*/ */
int ME_CharOfsFromRunOfs(ME_TextEditor *editor, ME_DisplayItem *pRun, int nOfs) int ME_CharOfsFromRunOfs(ME_TextEditor *editor, const ME_DisplayItem *pPara,
const ME_DisplayItem *pRun, int nOfs)
{ {
ME_DisplayItem *pPara; assert(pRun && pRun->type == diRun);
assert(pPara && pPara->type == diParagraph);
assert(pRun->type == diRun); return pPara->member.para.nCharOfs + pRun->member.run.nCharOfs + nOfs;
assert(pRun->member.run.nCharOfs != -1);
pPara = ME_FindItemBack(pRun, diParagraph);
assert(pPara);
assert(pPara->type==diParagraph);
return pPara->member.para.nCharOfs + pRun->member.run.nCharOfs
+ ME_VPosToPos(pRun->member.run.strText, nOfs);
} }
/****************************************************************************** /******************************************************************************
* ME_CursorFromCharOfs * ME_CursorFromCharOfs
* *
* Converts a character offset (relative to the start of the document) to * Converts a character offset (relative to the start of the document) to
* a cursor structure (which contains a run and a position relative to that * a cursor structure (which contains a run and a position relative to that
* run). * run).
*/ */
void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor) void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor)
{ {
ME_RunOfsFromCharOfs(editor, nCharOfs, &pCursor->pRun, &pCursor->nOffset); ME_RunOfsFromCharOfs(editor, nCharOfs, &pCursor->pPara,
&pCursor->pRun, &pCursor->nOffset);
} }
/****************************************************************************** /******************************************************************************
@ -179,13 +174,14 @@ void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCurso
* (absolute offset being an offset relative to the start of the document). * (absolute offset being an offset relative to the start of the document).
* Kind of a "global to local" offset conversion. * Kind of a "global to local" offset conversion.
*/ */
void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs) void ME_RunOfsFromCharOfs(ME_TextEditor *editor,
int nCharOfs,
ME_DisplayItem **ppPara,
ME_DisplayItem **ppRun,
int *pOfs)
{ {
ME_DisplayItem *item, *next_item; ME_DisplayItem *item, *next_item;
assert(ppRun);
assert(pOfs);
nCharOfs = max(nCharOfs, 0); nCharOfs = max(nCharOfs, 0);
nCharOfs = min(nCharOfs, ME_GetTextLength(editor)); nCharOfs = min(nCharOfs, ME_GetTextLength(editor));
@ -197,6 +193,7 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **
} while (next_item->member.para.nCharOfs <= nCharOfs); } while (next_item->member.para.nCharOfs <= nCharOfs);
assert(item->type == diParagraph); assert(item->type == diParagraph);
nCharOfs -= item->member.para.nCharOfs; nCharOfs -= item->member.para.nCharOfs;
if (ppPara) *ppPara = item;
/* Find the run at the offset. */ /* Find the run at the offset. */
next_item = ME_FindItemFwd(item, diRun); next_item = ME_FindItemFwd(item, diRun);
@ -208,8 +205,8 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **
assert(item->type == diRun); assert(item->type == diRun);
nCharOfs -= item->member.run.nCharOfs; nCharOfs -= item->member.run.nCharOfs;
*ppRun = item; if (ppRun) *ppRun = item;
*pOfs = nCharOfs; if (pOfs) *pOfs = nCharOfs;
} }
/****************************************************************************** /******************************************************************************
@ -229,7 +226,7 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p)
for (i=0; i<editor->nCursors; i++) { for (i=0; i<editor->nCursors; i++) {
if (editor->pCursors[i].pRun == pNext) { if (editor->pCursors[i].pRun == pNext) {
editor->pCursors[i].pRun = p; editor->pCursors[i].pRun = p;
editor->pCursors[i].nOffset += ME_StrVLen(p->member.run.strText); editor->pCursors[i].nOffset += p->member.run.strText->nLen;
} }
} }
@ -247,10 +244,10 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p)
/****************************************************************************** /******************************************************************************
* ME_SplitRun * ME_SplitRun
* *
* Splits a run into two in a given place. It also updates the screen position * Splits a run into two in a given place. It also updates the screen position
* and size (extent) of the newly generated runs. * and size (extent) of the newly generated runs.
*/ */
ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar) ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar)
{ {
ME_TextEditor *editor = wc->context->editor; ME_TextEditor *editor = wc->context->editor;
@ -306,7 +303,7 @@ ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_DisplayItem *item, i
ME_DisplayItem *item2; ME_DisplayItem *item2;
ME_Run *run2; ME_Run *run2;
int i; int i;
assert(nVChar > 0 && nVChar < ME_StrVLen(run->strText)); assert(nVChar > 0 && nVChar < run->strText->nLen);
assert(item->type == diRun); assert(item->type == diRun);
assert(!(item->member.run.nFlags & MERF_NONTEXT)); assert(!(item->member.run.nFlags & MERF_NONTEXT));
assert(item->member.run.nCharOfs != -1); assert(item->member.run.nCharOfs != -1);
@ -314,8 +311,7 @@ ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_DisplayItem *item, i
item2 = ME_MakeRun(run->style, item2 = ME_MakeRun(run->style,
ME_VSplitString(run->strText, nVChar), run->nFlags&MERF_SPLITMASK); ME_VSplitString(run->strText, nVChar), run->nFlags&MERF_SPLITMASK);
item2->member.run.nCharOfs = item->member.run.nCharOfs+ item2->member.run.nCharOfs = item->member.run.nCharOfs + nVChar;
ME_VPosToPos(item->member.run.strText, nVChar);
run2 = &item2->member.run; run2 = &item2->member.run;
ME_InsertBefore(item->next, item2); ME_InsertBefore(item->next, item2);
@ -374,75 +370,76 @@ ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem
/****************************************************************************** /******************************************************************************
* ME_InsertRunAtCursor * ME_InsertRunAtCursor
* *
* Inserts a new run with given style, flags and content at a given position, * Inserts a new run with given style, flags and content at a given position,
* which is passed as a cursor structure (which consists of a run and * which is passed as a cursor structure (which consists of a run and
* a run-relative character offset). * a run-relative character offset).
*/ */
ME_DisplayItem * ME_DisplayItem *
ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style,
const WCHAR *str, int len, int flags) const WCHAR *str, int len, int flags)
{ {
ME_DisplayItem *pDI; ME_DisplayItem *pDI;
ME_UndoItem *pUI; ME_UndoItem *pUI;
if (cursor->nOffset) { if (cursor->nOffset) {
/* We're inserting at the middle of the existing run, which means that /* We're inserting at the middle of the existing run, which means that
* that run must be split. It isn't always necessary, but */ * that run must be split. It isn't always necessary, but */
cursor->pRun = ME_SplitRunSimple(editor, cursor->pRun, cursor->nOffset); cursor->pRun = ME_SplitRunSimple(editor, cursor->pRun, cursor->nOffset);
cursor->nOffset = 0; cursor->nOffset = 0;
} }
pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL); pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL);
if (pUI) { if (pUI) {
pUI->nStart = (ME_GetParagraph(cursor->pRun)->member.para.nCharOfs pUI->nStart = cursor->pPara->member.para.nCharOfs
+ cursor->pRun->member.run.nCharOfs); + cursor->pRun->member.run.nCharOfs;
pUI->nLen = len; pUI->nLen = len;
} }
pDI = ME_MakeRun(style, ME_MakeStringN(str, len), flags); pDI = ME_MakeRun(style, ME_MakeStringN(str, len), flags);
pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs; pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs;
ME_InsertBefore(cursor->pRun, pDI); ME_InsertBefore(cursor->pRun, pDI);
TRACE("Shift length:%d\n", len); TRACE("Shift length:%d\n", len);
ME_PropagateCharOffset(cursor->pRun, len); ME_PropagateCharOffset(cursor->pRun, len);
ME_GetParagraph(cursor->pRun)->member.para.nFlags |= MEPF_REWRAP; cursor->pPara->member.para.nFlags |= MEPF_REWRAP;
return pDI; return pDI;
} }
/****************************************************************************** /******************************************************************************
* ME_UpdateRunFlags * ME_UpdateRunFlags
* *
* Determine some of run attributes given its content (style, text content). * Determine some of run attributes given its content (style, text content).
* Some flags cannot be determined by this function (MERF_GRAPHICS, * Some flags cannot be determined by this function (MERF_GRAPHICS,
* MERF_ENDPARA) * MERF_ENDPARA)
*/ */
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run) void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run)
{ {
assert(run->nCharOfs != -1); ME_String *strText = run->strText;
assert(run->nCharOfs >= 0);
if (RUN_IS_HIDDEN(run) || run->nFlags & MERF_TABLESTART) if (RUN_IS_HIDDEN(run) || run->nFlags & MERF_TABLESTART)
run->nFlags |= MERF_HIDDEN; run->nFlags |= MERF_HIDDEN;
else else
run->nFlags &= ~MERF_HIDDEN; run->nFlags &= ~MERF_HIDDEN;
if (ME_IsSplitable(run->strText)) if (ME_IsSplitable(strText))
run->nFlags |= MERF_SPLITTABLE; run->nFlags |= MERF_SPLITTABLE;
else else
run->nFlags &= ~MERF_SPLITTABLE; run->nFlags &= ~MERF_SPLITTABLE;
if (!(run->nFlags & MERF_NOTEXT)) { if (!(run->nFlags & MERF_NOTEXT)) {
if (ME_IsWhitespaces(run->strText)) if (ME_IsWhitespaces(strText))
run->nFlags |= MERF_WHITESPACE | MERF_STARTWHITE | MERF_ENDWHITE; run->nFlags |= MERF_WHITESPACE | MERF_STARTWHITE | MERF_ENDWHITE;
else else
{ {
run->nFlags &= ~MERF_WHITESPACE; run->nFlags &= ~MERF_WHITESPACE;
if (ME_IsWSpace(ME_GetCharFwd(run->strText,0))) if (ME_IsWSpace(strText->szData[0]))
run->nFlags |= MERF_STARTWHITE; run->nFlags |= MERF_STARTWHITE;
else else
run->nFlags &= ~MERF_STARTWHITE; run->nFlags &= ~MERF_STARTWHITE;
if (ME_IsWSpace(ME_GetCharBack(run->strText,0))) if (ME_IsWSpace(strText->szData[strText->nLen - 1]))
run->nFlags |= MERF_ENDWHITE; run->nFlags |= MERF_ENDWHITE;
else else
run->nFlags &= ~MERF_ENDWHITE; run->nFlags &= ~MERF_ENDWHITE;
@ -486,7 +483,7 @@ int ME_CharFromPoint(ME_Context *c, int cx, ME_Run *run)
if (c->editor->cPasswordMask) if (c->editor->cPasswordMask)
{ {
ME_String *strMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText)); ME_String *strMasked = ME_MakeStringR(c->editor->cPasswordMask, run->strText->nLen);
GetTextExtentExPointW(c->hDC, strMasked->szData, run->strText->nLen, GetTextExtentExPointW(c->hDC, strMasked->szData, run->strText->nLen,
cx, &fit, NULL, &sz); cx, &fit, NULL, &sz);
ME_DestroyString(strMasked); ME_DestroyString(strMasked);
@ -504,21 +501,21 @@ int ME_CharFromPoint(ME_Context *c, int cx, ME_Run *run)
/****************************************************************************** /******************************************************************************
* ME_CharFromPointCursor * ME_CharFromPointCursor
* *
* Returns a character position inside the run given a run-relative * Returns a character position inside the run given a run-relative
* pixel horizontal position. This version rounds to the nearest character edge * pixel horizontal position. This version rounds to the nearest character edge
* (ie. if the second character is at pixel position 8, then for cx=0..3 * (ie. if the second character is at pixel position 8, then for cx=0..3
* it returns 0, and for cx=4..7 it returns 1). * it returns 0, and for cx=4..7 it returns 1).
* *
* It is used for mouse click handling, for better usability (and compatibility * It is used for mouse click handling, for better usability (and compatibility
* with the native control). * with the native control).
*/ */
int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run) int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
{ {
ME_String *strRunText; ME_String *strRunText;
/* This could point to either the run's real text, or it's masked form in a password control */ /* This could point to either the run's real text, or it's masked form in a password control */
int fit = 0, fit1 = 0; int fit = 0;
ME_Context c; ME_Context c;
HGDIOBJ hOldFont; HGDIOBJ hOldFont;
SIZE sz, sz2, sz3; SIZE sz, sz2, sz3;
@ -543,7 +540,7 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
} }
if (editor->cPasswordMask) if (editor->cPasswordMask)
strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(run->strText)); strRunText = ME_MakeStringR(editor->cPasswordMask, run->strText->nLen);
else else
strRunText = run->strText; strRunText = run->strText;
@ -552,18 +549,15 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
cx, &fit, NULL, &sz); cx, &fit, NULL, &sz);
if (fit != strRunText->nLen) if (fit != strRunText->nLen)
{ {
int chars = 1;
GetTextExtentPoint32W(c.hDC, strRunText->szData, fit, &sz2); GetTextExtentPoint32W(c.hDC, strRunText->szData, fit, &sz2);
fit1 = ME_StrRelPos(strRunText, fit, &chars); GetTextExtentPoint32W(c.hDC, strRunText->szData, fit + 1, &sz3);
GetTextExtentPoint32W(c.hDC, strRunText->szData, fit1, &sz3);
if (cx >= (sz2.cx+sz3.cx)/2) if (cx >= (sz2.cx+sz3.cx)/2)
fit = fit1; fit = fit + 1;
} }
if (editor->cPasswordMask) if (editor->cPasswordMask)
ME_DestroyString(strRunText); ME_DestroyString(strRunText);
ME_UnselectStyleFont(&c, run->style, hOldFont); ME_UnselectStyleFont(&c, run->style, hOldFont);
ME_DestroyContext(&c); ME_DestroyContext(&c);
return fit; return fit;
@ -584,10 +578,10 @@ static void ME_GetTextExtent(ME_Context *c, LPCWSTR szText, int nChars, ME_Style
/****************************************************************************** /******************************************************************************
* ME_PointFromChar * ME_PointFromChar
* *
* Returns a run-relative pixel position given a run-relative character * Returns a run-relative pixel position given a run-relative character
* position (character offset) * position (character offset)
*/ */
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset) int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
{ {
SIZE size; SIZE size;
@ -600,19 +594,19 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
{ {
if (nOffset) if (nOffset)
ME_GetOLEObjectSize(&c, pRun, &size); ME_GetOLEObjectSize(&c, pRun, &size);
ITextHost_TxReleaseDC(editor->texthost, c.hDC); ME_DestroyContext(&c);
return nOffset != 0; return nOffset != 0;
} else if (pRun->nFlags & MERF_ENDPARA) { } else if (pRun->nFlags & MERF_ENDPARA) {
nOffset = 0; nOffset = 0;
} }
if (editor->cPasswordMask) if (editor->cPasswordMask)
strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(pRun->strText)); strRunText = ME_MakeStringR(editor->cPasswordMask, pRun->strText->nLen);
else else
strRunText = pRun->strText; strRunText = pRun->strText;
ME_GetTextExtent(&c, strRunText->szData, nOffset, pRun->style, &size); ME_GetTextExtent(&c, strRunText->szData, nOffset, pRun->style, &size);
ITextHost_TxReleaseDC(editor->texthost, c.hDC); ME_DestroyContext(&c);
if (editor->cPasswordMask) if (editor->cPasswordMask)
ME_DestroyString(strRunText); ME_DestroyString(strRunText);
return size.cx; return size.cx;
@ -628,7 +622,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
int startx, int *pAscent, int *pDescent) int startx, int *pAscent, int *pDescent)
{ {
SIZE size; SIZE size;
int nMaxLen = ME_StrVLen(run->strText); int nMaxLen = run->strText->nLen;
if (nLen>nMaxLen) if (nLen>nMaxLen)
nLen = nMaxLen; nLen = nMaxLen;
@ -721,7 +715,7 @@ void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Ru
run->nWidth = 0; run->nWidth = 0;
else else
{ {
int nEnd = ME_StrVLen(run->strText); int nEnd = run->strText->nLen;
SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, startx, SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, startx,
&run->nAscent, &run->nDescent); &run->nAscent, &run->nDescent);
run->nWidth = size.cx; run->nWidth = size.cx;
@ -783,7 +777,7 @@ void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W
if (tmp2.nOffset) if (tmp2.nOffset)
tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset); tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset);
para = ME_GetParagraph(tmp.pRun); para = tmp.pPara;
para->member.para.nFlags |= MEPF_REWRAP; para->member.para.nFlags |= MEPF_REWRAP;
while(tmp.pRun != tmp2.pRun) while(tmp.pRun != tmp2.pRun)
@ -878,17 +872,17 @@ void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
/****************************************************************************** /******************************************************************************
* ME_GetCharFormat * ME_GetCharFormat
* *
* Returns the style consisting of those attributes which are consistently set * Returns the style consisting of those attributes which are consistently set
* in the whole character range. * in the whole character range.
*/ */
void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *pFmt) void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *pFmt)
{ {
ME_DisplayItem *run, *run_end; ME_DisplayItem *run, *run_end;
int nOffset, nOffset2; int nOffset, nOffset2;
CHARFORMAT2W tmp; CHARFORMAT2W tmp;
ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset); ME_RunOfsFromCharOfs(editor, nFrom, NULL, &run, &nOffset);
if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */ if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
{ {
if (!nOffset) if (!nOffset)
@ -905,7 +899,7 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */ if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
nTo--; nTo--;
ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2); ME_RunOfsFromCharOfs(editor, nTo, NULL, &run_end, &nOffset2);
ME_GetRunCharFormat(editor, run, pFmt); ME_GetRunCharFormat(editor, run, pFmt);

View file

@ -18,61 +18,49 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "editor.h" #include "editor.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit); WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static int ME_GetOptimalBuffer(int nLen) static int ME_GetOptimalBuffer(int nLen)
{ {
return ((2*nLen+1)+128)&~63; /* FIXME: This seems wasteful for tabs and end of lines strings,
* since they have a small fixed length. */
return ((sizeof(WCHAR) * nLen) + 128) & ~63;
} }
ME_String *ME_MakeString(LPCWSTR szText) /* Create a buffer (uninitialized string) of size nMaxChars */
static ME_String *ME_MakeStringB(int nMaxChars)
{ {
ME_String *s = ALLOC_OBJ(ME_String); ME_String *s = ALLOC_OBJ(ME_String);
s->nLen = lstrlenW(szText);
s->nBuffer = ME_GetOptimalBuffer(s->nLen+1); s->nLen = nMaxChars;
s->nBuffer = ME_GetOptimalBuffer(s->nLen + 1);
s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer); s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
lstrcpyW(s->szData, szText); s->szData[s->nLen] = 0;
return s; return s;
} }
ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars)
{ {
ME_String *s = ALLOC_OBJ(ME_String); ME_String *s = ME_MakeStringB(nMaxChars);
/* Native allows NULL chars */
s->nLen = nMaxChars; memcpy(s->szData, szText, s->nLen * sizeof(WCHAR));
s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
/* Native allows NUL chars */
memmove(s->szData, szText, s->nLen * sizeof(WCHAR));
s->szData[s->nLen] = 0;
return s; return s;
} }
ME_String *ME_MakeString(LPCWSTR szText)
{
return ME_MakeStringN(szText, lstrlenW(szText));
}
/* Make a string by repeating a char nMaxChars times */
ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars)
{ /* Make a string by repeating a char nMaxChars times */ {
int i; int i;
ME_String *s = ALLOC_OBJ(ME_String); ME_String *s = ME_MakeStringB(nMaxChars);
for (i = 0; i < nMaxChars; i++)
s->nLen = nMaxChars;
s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
for (i = 0;i<nMaxChars;i++)
s->szData[i] = cRepeat; s->szData[i] = cRepeat;
s->szData[s->nLen] = 0;
return s;
}
ME_String *ME_MakeStringB(int nMaxChars)
{ /* Create a buffer (uninitialized string) of size nMaxChars */
ME_String *s = ALLOC_OBJ(ME_String);
s->nLen = nMaxChars;
s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
s->szData[s->nLen] = 0;
return s; return s;
} }
@ -90,35 +78,25 @@ void ME_DestroyString(ME_String *s)
void ME_AppendString(ME_String *s1, const ME_String *s2) void ME_AppendString(ME_String *s1, const ME_String *s2)
{ {
if (s1->nLen+s2->nLen+1 <= s1->nBuffer) { if (s1->nLen+s2->nLen+1 <= s1->nBuffer)
lstrcpyW(s1->szData+s1->nLen, s2->szData);
s1->nLen += s2->nLen;
}
else
{ {
memcpy(s1->szData + s1->nLen, s2->szData, s2->nLen * sizeof(WCHAR));
s1->nLen += s2->nLen;
s1->szData[s1->nLen] = 0;
} else {
WCHAR *buf; WCHAR *buf;
s1->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1); s1->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1);
buf = ALLOC_N_OBJ(WCHAR, s1->nBuffer); buf = ALLOC_N_OBJ(WCHAR, s1->nBuffer);
lstrcpyW(buf, s1->szData); memcpy(buf, s1->szData, s1->nLen * sizeof(WCHAR));
lstrcpyW(buf+s1->nLen, s2->szData); memcpy(buf + s1->nLen, s2->szData, s2->nLen * sizeof(WCHAR));
FREE_OBJ(s1->szData); FREE_OBJ(s1->szData);
s1->szData = buf; s1->szData = buf;
s1->nLen += s2->nLen; s1->nLen += s2->nLen;
s1->szData[s1->nLen] = 0;
} }
} }
ME_String *ME_ConcatString(const ME_String *s1, const ME_String *s2)
{
ME_String *s = ALLOC_OBJ(ME_String);
s->nLen = s1->nLen+s2->nLen;
s->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1);
s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
lstrcpyW(s->szData, s1->szData);
lstrcpyW(s->szData+s1->nLen, s2->szData);
return s;
}
ME_String *ME_VSplitString(ME_String *orig, int charidx) ME_String *ME_VSplitString(ME_String *orig, int charidx)
{ {
ME_String *s; ME_String *s;
@ -163,113 +141,17 @@ int ME_IsSplitable(const ME_String *s)
return 0; return 0;
} }
/* FIXME multibyte */
/*
int ME_CalcSkipChars(ME_String *s)
{
int cnt = 0;
while(cnt < s->nLen && s->szData[s->nLen-1-cnt]==' ')
cnt++;
return cnt;
}
*/
int ME_StrLen(const ME_String *s) {
return s->nLen;
}
int ME_StrVLen(const ME_String *s) {
return s->nLen;
}
int ME_StrRelPos(const ME_String *s, int nVChar, int *pRelChars)
{
int nRelChars = *pRelChars;
TRACE("%s,%d,&%d\n", debugstr_w(s->szData), nVChar, *pRelChars);
assert(*pRelChars);
if (!nRelChars)
return nVChar;
if (nRelChars>0)
nRelChars = min(*pRelChars, s->nLen - nVChar);
else
nRelChars = max(*pRelChars, -nVChar);
nVChar += nRelChars;
*pRelChars -= nRelChars;
return nVChar;
}
int ME_StrRelPos2(const ME_String *s, int nVChar, int nRelChars)
{
return ME_StrRelPos(s, nVChar, &nRelChars);
}
int ME_VPosToPos(ME_String *s, int nVPos)
{
return nVPos;
/*
int i = 0, len = 0;
if (!nVPos)
return 0;
while (i < s->nLen)
{
if (i == nVPos)
return len;
if (s->szData[i]=='\\') i++;
i++;
len++;
}
return len;
*/
}
int ME_PosToVPos(const ME_String *s, int nPos)
{
if (!nPos)
return 0;
return ME_StrRelPos2(s, 0, nPos);
}
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars) void ME_StrDeleteV(ME_String *s, int nVChar, int nChars)
{ {
int end_ofs; int end_ofs = nVChar + nChars;
assert(nVChar >=0 && nVChar <= s->nLen);
assert(nChars >= 0); assert(nChars >= 0);
assert(nVChar+nChars <= s->nLen); assert(nVChar >= 0);
end_ofs = ME_StrRelPos2(s, nVChar, nChars);
assert(end_ofs <= s->nLen); assert(end_ofs <= s->nLen);
memmove(s->szData+nVChar, s->szData+end_ofs, 2*(s->nLen+1-end_ofs));
s->nLen -= (end_ofs - nVChar);
}
int ME_GetCharFwd(const ME_String *s, int nPos) memmove(s->szData + nVChar, s->szData + end_ofs,
{ (s->nLen - end_ofs + 1) * sizeof(WCHAR));
int nVPos = 0; s->nLen -= nChars;
assert(nPos < ME_StrLen(s));
if (nPos)
nVPos = ME_StrRelPos2(s, nVPos, nPos);
if (nVPos < s->nLen)
return s->szData[nVPos];
return -1;
}
int ME_GetCharBack(const ME_String *s, int nPos)
{
int nVPos = ME_StrVLen(s);
assert(nPos < ME_StrLen(s));
if (nPos)
nVPos = ME_StrRelPos2(s, nVPos, -nPos);
if (nVPos < s->nLen)
return s->szData[nVPos];
return -1;
} }
int ME_FindNonWhitespaceV(const ME_String *s, int nVChar) { int ME_FindNonWhitespaceV(const ME_String *s, int nVChar) {

View file

@ -71,12 +71,6 @@ CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from)
return (from->cbSize >= sizeof(CHARFORMAT2W)) ? from : NULL; return (from->cbSize >= sizeof(CHARFORMAT2W)) ? from : NULL;
} }
void ME_CopyToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from)
{
if (ME_ToCF2W(to, from) == from)
*to = *from;
}
static CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from) static CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
{ {
assert(from->cbSize == sizeof(CHARFORMAT2W)); assert(from->cbSize == sizeof(CHARFORMAT2W));

View file

@ -70,6 +70,7 @@ static ME_DisplayItem* ME_InsertEndParaFromCursor(ME_TextEditor *editor,
} }
tp = ME_SplitParagraph(editor, cursor->pRun, pStyle, eol_str, paraFlags); tp = ME_SplitParagraph(editor, cursor->pRun, pStyle, eol_str, paraFlags);
cursor->pPara = tp;
cursor->pRun = ME_FindItemFwd(tp, diRun); cursor->pRun = ME_FindItemFwd(tp, diRun);
return tp; return tp;
} }
@ -89,6 +90,7 @@ ME_DisplayItem* ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor,
ME_DisplayItem *prev_para, *end_para; ME_DisplayItem *prev_para, *end_para;
ME_Cursor savedCursor = editor->pCursors[0]; ME_Cursor savedCursor = editor->pCursors[0];
ME_DisplayItem *startRowPara; ME_DisplayItem *startRowPara;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -96,7 +98,7 @@ ME_DisplayItem* ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor,
editor->pCursors[0] = savedCursor; editor->pCursors[0] = savedCursor;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
end_para = ME_GetParagraph(editor->pCursors[0].pRun)->member.para.next_para; end_para = editor->pCursors[0].pPara->member.para.next_para;
prev_para = startRowPara->member.para.next_para; prev_para = startRowPara->member.para.next_para;
para = prev_para->member.para.next_para; para = prev_para->member.para.next_para;
while (para != end_para) while (para != end_para)
@ -276,9 +278,9 @@ void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars)
ME_Cursor c, c2; ME_Cursor c, c2;
ME_DisplayItem *this_para, *end_para; ME_DisplayItem *this_para, *end_para;
ME_CursorFromCharOfs(editor, nOfs, &c); ME_CursorFromCharOfs(editor, nOfs, &c);
this_para = ME_GetParagraph(c.pRun); this_para = c.pPara;
ME_CursorFromCharOfs(editor, nOfs + *nChars, &c2); ME_CursorFromCharOfs(editor, nOfs + *nChars, &c2);
end_para = ME_GetParagraph(c2.pRun); end_para = c2.pPara;
if (c2.pRun->member.run.nFlags & MERF_ENDPARA) { if (c2.pRun->member.run.nFlags & MERF_ENDPARA) {
/* End offset might be in the middle of the end paragraph run. /* 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 * If this is the case, then we need to use the next paragraph as the last
@ -399,14 +401,15 @@ ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor,
ME_DisplayItem *insertedCell, *para, *cell, *prevTableEnd; ME_DisplayItem *insertedCell, *para, *cell, *prevTableEnd;
cell = ME_FindItemFwd(ME_GetTableRowStart(table_row), diCell); cell = ME_FindItemFwd(ME_GetTableRowStart(table_row), diCell);
prevTableEnd = ME_GetTableRowEnd(table_row); prevTableEnd = ME_GetTableRowEnd(table_row);
run = prevTableEnd->member.para.next_para; para = prevTableEnd->member.para.next_para;
run = ME_FindItemFwd(run, diRun); run = ME_FindItemFwd(para, diRun);
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = run; editor->pCursors[0].pRun = run;
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
para = ME_InsertTableRowStartFromCursor(editor); para = ME_InsertTableRowStartFromCursor(editor);
insertedCell = ME_FindItemFwd(para, diCell); insertedCell = ME_FindItemFwd(para, diCell);
/* Copy cell properties */ /* Copy cell properties */
insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary; insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary;
insertedCell->member.cell.border = cell->member.cell.border; insertedCell->member.cell.border = cell->member.cell.border;
while (cell->member.cell.next_cell) { while (cell->member.cell.next_cell) {
@ -425,6 +428,7 @@ ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor,
run = ME_FindItemBack(table_row->member.para.next_para, diRun); run = ME_FindItemBack(table_row->member.para.next_para, diRun);
pFmt = table_row->member.para.pFmt; pFmt = table_row->member.para.pFmt;
assert(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE); assert(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE);
editor->pCursors[0].pPara = table_row;
editor->pCursors[0].pRun = run; editor->pCursors[0].pRun = run;
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -474,6 +478,7 @@ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor,
para = ME_AppendTableRow(editor, ME_GetTableRowStart(para)); para = ME_AppendTableRow(editor, ME_GetTableRowStart(para));
/* Put cursor at the start of the new table row */ /* Put cursor at the start of the new table row */
para = para->member.para.next_para; para = para->member.para.next_para;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -483,10 +488,12 @@ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor,
} }
/* Select cell */ /* Select cell */
editor->pCursors[1].pRun = ME_FindItemFwd(cell, diRun); editor->pCursors[1].pRun = ME_FindItemFwd(cell, diRun);
editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun);
editor->pCursors[1].nOffset = 0; editor->pCursors[1].nOffset = 0;
assert(editor->pCursors[0].pRun); assert(editor->pCursors[0].pRun);
cell = cell->member.cell.next_cell; cell = cell->member.cell.next_cell;
editor->pCursors[0].pRun = ME_FindItemBack(cell, diRun); editor->pCursors[0].pRun = ME_FindItemBack(cell, diRun);
editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
assert(editor->pCursors[1].pRun); assert(editor->pCursors[1].pRun);
} else { /* v1.0 - 3.0 */ } else { /* v1.0 - 3.0 */
@ -508,6 +515,7 @@ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor,
{ {
run = ME_FindItemFwd(para, diRun); run = ME_FindItemFwd(para, diRun);
assert(run); assert(run);
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = run; editor->pCursors[0].pRun = run;
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
i = 1; i = 1;
@ -515,6 +523,7 @@ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor,
/* Insert table row */ /* Insert table row */
para = ME_AppendTableRow(editor, para->member.para.prev_para); para = ME_AppendTableRow(editor, para->member.para.prev_para);
/* Put cursor at the start of the new table row */ /* Put cursor at the start of the new table row */
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
@ -526,6 +535,7 @@ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor,
if (i == 0) if (i == 0)
run = ME_FindItemFwd(run, diRun); run = ME_FindItemFwd(run, diRun);
editor->pCursors[i].pRun = run; editor->pCursors[i].pRun = run;
editor->pCursors[i].pPara = ME_GetParagraph(run);
editor->pCursors[i].nOffset = 0; editor->pCursors[i].nOffset = 0;
} }
} }
@ -595,12 +605,13 @@ void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow)
* without a selection. */ * without a selection. */
void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor) void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor)
{ {
ME_DisplayItem *para = ME_GetParagraph(editor->pCursors[0].pRun); ME_DisplayItem *para = editor->pCursors[0].pPara;
if (para == ME_GetParagraph(editor->pCursors[1].pRun) && if (para == editor->pCursors[1].pPara &&
para->member.para.nFlags & MEPF_ROWSTART) { para->member.para.nFlags & MEPF_ROWSTART) {
/* The cursors should not be at the hidden start row paragraph without /* The cursors should not be at the hidden start row paragraph without
* a selection, so the cursor is moved into the first cell. */ * a selection, so the cursor is moved into the first cell. */
para = para->member.para.next_para; para = para->member.para.next_para;
editor->pCursors[0].pPara = para;
editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
editor->pCursors[0].nOffset = 0; editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];

View file

@ -59,7 +59,7 @@ ITextHost *ME_CreateTextHost(HWND hwnd, BOOL bEmulateVersion10)
editor = ME_MakeEditor((ITextHost*)texthost, bEmulateVersion10); editor = ME_MakeEditor((ITextHost*)texthost, bEmulateVersion10);
editor->exStyleFlags = GetWindowLongW(hwnd, GWL_EXSTYLE); editor->exStyleFlags = GetWindowLongW(hwnd, GWL_EXSTYLE);
editor->hWnd = hwnd; /* FIXME: Remove editor's dependance on hWnd */ editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */
SetWindowLongPtrW(hwnd, 0, (LONG_PTR)editor); SetWindowLongPtrW(hwnd, 0, (LONG_PTR)editor);
} }
@ -258,14 +258,14 @@ HRESULT WINAPI ITextHostImpl_TxActivate(ITextHost *iface,
LONG *plOldState) LONG *plOldState)
{ {
ITextHostImpl *This = (ITextHostImpl *)iface; ITextHostImpl *This = (ITextHostImpl *)iface;
*plOldState = (LONG)SetActiveWindow(This->hWnd); *plOldState = HandleToLong(SetActiveWindow(This->hWnd));
return (*plOldState ? S_OK : E_FAIL); return (*plOldState ? S_OK : E_FAIL);
} }
HRESULT WINAPI ITextHostImpl_TxDeactivate(ITextHost *iface, HRESULT WINAPI ITextHostImpl_TxDeactivate(ITextHost *iface,
LONG lNewState) LONG lNewState)
{ {
HWND ret = SetActiveWindow((HWND)lNewState); HWND ret = SetActiveWindow(LongToHandle(lNewState));
return (ret ? S_OK : E_FAIL); return (ret ? S_OK : E_FAIL);
} }
@ -323,7 +323,7 @@ HRESULT WINAPI ITextHostImpl_TxGetScrollBars(ITextHost *iface,
DWORD *pdwScrollBar) DWORD *pdwScrollBar)
{ {
ITextHostImpl *This = (ITextHostImpl *)iface; ITextHostImpl *This = (ITextHostImpl *)iface;
ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongW(This->hWnd, 0); ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0);
const DWORD mask = WS_VSCROLL| const DWORD mask = WS_VSCROLL|
WS_HSCROLL| WS_HSCROLL|
ES_AUTOVSCROLL| ES_AUTOVSCROLL|
@ -452,8 +452,6 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface,
HWND parent = GetParent(hwnd); HWND parent = GetParent(hwnd);
UINT id = GetWindowLongW(hwnd, GWLP_ID); UINT id = GetWindowLongW(hwnd, GWLP_ID);
/* Note: EN_MSGFILTER is documented as not being sent to TxNotify */
switch (iNotify) switch (iNotify)
{ {
case EN_DROPFILES: case EN_DROPFILES:
@ -492,6 +490,9 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface,
SendMessageW(parent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd); SendMessageW(parent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd);
break; break;
case EN_MSGFILTER:
FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n");
/* fall through */
default: default:
return E_FAIL; return E_FAIL;
} }

View file

@ -156,8 +156,10 @@ HRESULT WINAPI fnTextSrv_TxSendMessage(ITextServices *iface,
{ {
ICOM_THIS_MULTI(ITextServicesImpl, lpVtbl, iface); ICOM_THIS_MULTI(ITextServicesImpl, lpVtbl, iface);
HRESULT hresult; HRESULT hresult;
LRESULT lresult;
*plresult = ME_HandleMessage(This->editor, msg, wparam, lparam, TRUE, &hresult); lresult = ME_HandleMessage(This->editor, msg, wparam, lparam, TRUE, &hresult);
if (plresult) *plresult = lresult;
return hresult; return hresult;
} }

View file

@ -316,7 +316,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
ME_Cursor tmp; ME_Cursor tmp;
ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp); ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
/* the only thing that's needed is paragraph offset, so no need to split runs */ /* the only thing that's needed is paragraph offset, so no need to split runs */
ME_JoinParagraphs(editor, ME_GetParagraph(tmp.pRun), TRUE); ME_JoinParagraphs(editor, tmp.pPara, TRUE);
break; break;
} }
case diUndoSplitParagraph: case diUndoSplitParagraph:
@ -329,7 +329,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
if (tmp.nOffset) if (tmp.nOffset)
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset); tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
assert(pUItem->eol_str); assert(pUItem->eol_str);
this_para = ME_GetParagraph(tmp.pRun); this_para = tmp.pPara;
bFixRowStart = this_para->member.para.nFlags & MEPF_ROWSTART; bFixRowStart = this_para->member.para.nFlags & MEPF_ROWSTART;
if (bFixRowStart) if (bFixRowStart)
{ {

View file

@ -42,10 +42,11 @@ static ME_DisplayItem *ME_MakeRow(int height, int baseline, int width)
return item; return item;
} }
static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para) static void ME_BeginRow(ME_WrapContext *wc)
{ {
PARAFORMAT2 *pFmt; PARAFORMAT2 *pFmt;
assert(para && para->type == diParagraph); ME_DisplayItem *para = wc->pPara;
pFmt = para->member.para.pFmt; pFmt = para->member.para.pFmt;
wc->pRowStart = NULL; wc->pRowStart = NULL;
wc->bOverflown = FALSE; wc->bOverflown = FALSE;
@ -77,7 +78,7 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para)
- (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin; - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
wc->bWordWrap = TRUE; wc->bWordWrap = TRUE;
} else { } else {
wc->nAvailWidth = wc->context->rcView.right - wc->context->rcView.left wc->nAvailWidth = wc->context->nAvailWidth
- (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin; - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
} }
wc->pt.x = wc->context->pt.x; wc->pt.x = wc->context->pt.x;
@ -94,7 +95,7 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
int ascent = 0, descent = 0, width=0, shift = 0, align = 0; int ascent = 0, descent = 0, width=0, shift = 0, align = 0;
PARAFORMAT2 *pFmt; PARAFORMAT2 *pFmt;
/* wrap text */ /* wrap text */
para = ME_GetParagraph(wc->pRowStart); para = wc->pPara;
pFmt = para->member.para.pFmt; pFmt = para->member.para.pFmt;
for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev) for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev)
@ -114,7 +115,8 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
WCHAR *text = p->member.run.strText->szData + len - 1; WCHAR *text = p->member.run.strText->szData + len - 1;
assert (len); assert (len);
while (len && *(text--) == ' ') if (~p->member.run.nFlags & MERF_GRAPHICS)
while (len && *(text--) == ' ')
len--; len--;
if (len) if (len)
{ {
@ -162,12 +164,12 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
ME_InsertBefore(wc->pRowStart, row); ME_InsertBefore(wc->pRowStart, row);
wc->nRow++; wc->nRow++;
wc->pt.y += row->member.row.nHeight; wc->pt.y += row->member.row.nHeight;
ME_BeginRow(wc, para); ME_BeginRow(wc);
} }
static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p) static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p)
{ {
ME_DisplayItem *para = p->member.para.prev_para; ME_DisplayItem *para = wc->pPara;
PARAFORMAT2 *pFmt = para->member.para.pFmt; PARAFORMAT2 *pFmt = para->member.para.pFmt;
if (wc->pRowStart) if (wc->pRowStart)
ME_InsertRowStart(wc, p); ME_InsertRowStart(wc, p);
@ -180,7 +182,7 @@ static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p)
} }
/* /*
p = p->member.para.prev_para->next; p = para->next;
while(p) { while(p) {
if (p->type == diParagraph || p->type == diTextEnd) if (p->type == diParagraph || p->type == diTextEnd)
return; return;
@ -200,7 +202,7 @@ static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p)
ME_UpdateRunFlags(wc->context->editor, &p->member.run); ME_UpdateRunFlags(wc->context->editor, &p->member.run);
ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, ME_CalcRunExtent(wc->context, &wc->pPara->member.para,
wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run); wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run);
} }
@ -253,7 +255,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
ME_Run *run = &p->member.run; ME_Run *run = &p->member.run;
idesp = i = ME_CharFromPoint(wc->context, loc, run); idesp = i = ME_CharFromPoint(wc->context, loc, run);
len = ME_StrVLen(run->strText); len = run->strText->nLen;
assert(len>0); assert(len>0);
assert(i<len); assert(i<len);
if (i) { if (i) {
@ -280,7 +282,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
piter = wc->pLastSplittableRun; piter = wc->pLastSplittableRun;
run = &piter->member.run; run = &piter->member.run;
len = ME_StrVLen(run->strText); len = run->strText->nLen;
/* don't split words */ /* don't split words */
i = ME_ReverseFindWhitespaceV(run->strText, len); i = ME_ReverseFindWhitespaceV(run->strText, len);
if (i == len) if (i == len)
@ -315,11 +317,9 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
else else
{ {
/* split point inside first character - no choice but split after that char */ /* split point inside first character - no choice but split after that char */
int chars = 1; if (len != 1) {
int pos2 = ME_StrRelPos(run->strText, 0, &chars);
if (pos2 != len) {
/* the run is more than 1 char, so we may split */ /* the run is more than 1 char, so we may split */
return ME_SplitRun(wc, piter, pos2); return ME_SplitRun(wc, piter, 1);
} }
/* the run is one char, can't split it */ /* the run is one char, can't split it */
return piter; return piter;
@ -339,7 +339,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
run->pt.x = wc->pt.x; run->pt.x = wc->pt.x;
run->pt.y = wc->pt.y; run->pt.y = wc->pt.y;
ME_WrapSizeRun(wc, p); ME_WrapSizeRun(wc, p);
len = ME_StrVLen(run->strText); len = run->strText->nLen;
if (wc->bOverflown) /* just skipping final whitespaces */ if (wc->bOverflown) /* just skipping final whitespaces */
{ {
@ -473,6 +473,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
pFmt = tp->member.para.pFmt; pFmt = tp->member.para.pFmt;
wc.context = c; wc.context = c;
wc.pPara = tp;
/* wc.para_style = tp->member.para.style; */ /* wc.para_style = tp->member.para.style; */
wc.style = NULL; wc.style = NULL;
if (tp->member.para.nFlags & MEPF_ROWEND) { if (tp->member.para.nFlags & MEPF_ROWEND) {
@ -511,7 +512,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
linespace = ME_GetParaLineSpace(c, &tp->member.para); linespace = ME_GetParaLineSpace(c, &tp->member.para);
ME_BeginRow(&wc, tp); ME_BeginRow(&wc);
for (p = tp->next; p!=tp->member.para.next_para; ) { for (p = tp->next; p!=tp->member.para.next_para; ) {
assert(p->type != diStartRow); assert(p->type != diStartRow);
if (p->type == diRun) { if (p->type == diRun) {

View file

@ -766,13 +766,11 @@ static BOOL
ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, int dwFormat) ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, int dwFormat)
{ {
ME_DisplayItem *p, *pEnd, *pPara; ME_DisplayItem *p, *pEnd, *pPara;
int nOffset, nEndLen; int nOffset, nEndLen;
ME_RunOfsFromCharOfs(editor, nStart, &p, &nOffset); ME_RunOfsFromCharOfs(editor, nStart, &pPara, &p, &nOffset);
ME_RunOfsFromCharOfs(editor, nStart+nChars, &pEnd, &nEndLen); ME_RunOfsFromCharOfs(editor, nStart+nChars, NULL, &pEnd, &nEndLen);
pPara = ME_GetParagraph(p);
if (!ME_StreamOutRTFHeader(pStream, dwFormat)) if (!ME_StreamOutRTFHeader(pStream, dwFormat))
return FALSE; return FALSE;
@ -891,7 +889,7 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
if (!ME_StreamOutRTFCharProps(pStream, &p->member.run.style->fmt)) if (!ME_StreamOutRTFCharProps(pStream, &p->member.run.style->fmt))
return FALSE; return FALSE;
nEnd = (p == pEnd) ? nEndLen : ME_StrLen(p->member.run.strText); nEnd = (p == pEnd) ? nEndLen : p->member.run.strText->nLen;
if (!ME_StreamOutRTFText(pStream, p->member.run.strText->szData + nOffset, nEnd - nOffset)) if (!ME_StreamOutRTFText(pStream, p->member.run.strText->szData + nOffset, nEnd - nOffset))
return FALSE; return FALSE;
nOffset = 0; nOffset = 0;
@ -922,7 +920,7 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
int nBufLen = 0; int nBufLen = 0;
BOOL success = TRUE; BOOL success = TRUE;
ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart); ME_RunOfsFromCharOfs(editor, nStart, NULL, &item, &nStart);
if (!item) if (!item)
return FALSE; return FALSE;
@ -933,7 +931,7 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
/* TODO: Handle SF_TEXTIZED */ /* TODO: Handle SF_TEXTIZED */
while (success && nChars && item) { while (success && nChars && item) {
nLen = min(nChars, ME_StrLen(item->member.run.strText) - nStart); nLen = min(nChars, item->member.run.strText->nLen - nStart);
if (!editor->bEmulateVersion10 && item->member.run.nFlags & MERF_ENDPARA) if (!editor->bEmulateVersion10 && item->member.run.nFlags & MERF_ENDPARA)
{ {