Commit 46b84aed authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

richedit: Added function to get selection cursors in order.

Previously the only convenient way to get the start and end of the selection was through offsets, which eventually need to get converted back into items in the linked list storing the text. The new function will help with eliminating these inefficiencies.
parent be0fb1ef
......@@ -27,16 +27,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static BOOL
ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs);
void ME_GetSelection(ME_TextEditor *editor, int *from, int *to)
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
{
*from = ME_GetCursorOfs(&editor->pCursors[0]);
*to = ME_GetCursorOfs(&editor->pCursors[1]);
if (*from > *to)
{
int tmp = *from;
*from = *to;
*to = tmp;
*to = tmp;
return 1;
}
return 0;
}
int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to)
{
if (ME_GetCursorOfs(&editor->pCursors[0]) < ME_GetCursorOfs(&editor->pCursors[1]))
{
*from = &editor->pCursors[0];
*to = &editor->pCursors[1];
return 0;
} else {
*from = &editor->pCursors[1];
*to = &editor->pCursors[0];
return 1;
}
}
......@@ -119,7 +135,7 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
if (from < 0)
{
int start, end;
ME_GetSelection(editor, &start, &end);
ME_GetSelectionOfs(editor, &start, &end);
editor->pCursors[1] = editor->pCursors[0];
ME_Repaint(editor);
ME_ClearTempStyle(editor);
......@@ -1496,22 +1512,11 @@ BOOL ME_IsSelection(ME_TextEditor *editor)
editor->pCursors[0].nOffset != editor->pCursors[1].nOffset;
}
static int ME_GetSelCursor(ME_TextEditor *editor, int dir)
{
int cdir = ME_GetCursorOfs(&editor->pCursors[0])
- ME_GetCursorOfs(&editor->pCursors[1]);
if (cdir*dir>0)
return 0;
else
return 1;
}
void ME_DeleteSelection(ME_TextEditor *editor)
{
int from, to;
ME_GetSelection(editor, &from, &to);
ME_DeleteTextAtCursor(editor, ME_GetSelCursor(editor,-1), to-from);
int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
ME_DeleteTextAtCursor(editor, nStartCursor, to - from);
}
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor)
......@@ -1527,11 +1532,11 @@ void ME_SendSelChange(ME_TextEditor *editor)
return;
sc.nmhdr.code = EN_SELCHANGE;
ME_GetSelection(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
ME_GetSelectionOfs(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
sc.seltyp = SEL_EMPTY;
if (sc.chrg.cpMin != sc.chrg.cpMax)
sc.seltyp |= SEL_TEXT;
if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* wth were RICHEDIT authors thinking ? */
if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */
sc.seltyp |= SEL_MULTICHAR;
TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n",
sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,
......
......@@ -1385,7 +1385,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
{
RTF_Info parser;
ME_Style *style;
int from, to, to2, nUndoMode;
int from, to, nUndoMode;
int nEventMask = editor->nEventMask;
ME_InStream inStream;
BOOL invalidRTF = FALSE;
......@@ -1393,7 +1393,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
TRACE("stream==%p editor==%p format==0x%X\n", stream, editor, format);
editor->nEventMask = 0;
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
if ((format & SFF_SELECTION) && (editor->mode & TM_RICHTEXT)) {
style = ME_GetSelectionInsertStyle(editor);
......@@ -1545,7 +1545,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
*/
if (stripLastCR) {
int newfrom, newto;
ME_GetSelection(editor, &newfrom, &newto);
ME_GetSelectionOfs(editor, &newfrom, &newto);
if (newto > to + (editor->bEmulateVersion10 ? 1 : 0)) {
WCHAR lastchar[3] = {'\0', '\0'};
int linebreakSize = editor->bEmulateVersion10 ? 2 : 1;
......@@ -1563,7 +1563,6 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_StreamInText(editor, format, &inStream, style);
else
ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
ME_GetSelection(editor, &to, &to2);
/* put the cursor at the top */
if (!(format & SFF_SELECTION))
ME_SetSelection(editor, 0, 0);
......@@ -1874,7 +1873,7 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
if (ex->flags & GT_SELECTION)
{
ME_GetSelection(editor, &nStart, &nCount);
ME_GetSelectionOfs(editor, &nStart, &nCount);
nCount -= nStart;
}
else
......@@ -2041,20 +2040,19 @@ static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
{
ME_DisplayItem *startPara, *endPara;
ME_DisplayItem *prev_para;
int from, to;
ME_Cursor *from, *to;
if (!editor->AutoURLDetect_bEnable) return;
ME_GetSelection(editor, &from, &to);
/* Find paragraph previous to the one that contains start cursor */
ME_RunOfsFromCharOfs(editor, from, &startPara, NULL, NULL);
startPara = from->pPara;
prev_para = startPara->member.para.prev_para;
if (prev_para->type == diParagraph) startPara = prev_para;
/* Find paragraph that contains end cursor */
ME_RunOfsFromCharOfs(editor, to, &endPara, NULL, NULL);
endPara = endPara->member.para.next_para;
endPara = to->pPara->member.para.next_para;
ME_UpdateLinkAttribute(editor,
startPara->member.para.nCharOfs,
......@@ -2140,7 +2138,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
return TRUE;
}
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
if (editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
{
if (!editor->bEmulateVersion10) { /* v4.1 */
......@@ -2264,7 +2262,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
CHARRANGE range;
BOOL result;
ME_GetSelection(editor, &range.cpMin, &range.cpMax);
ME_GetSelectionOfs(editor, &range.cpMin, &range.cpMax);
result = ME_Copy(editor, &range);
if (result && nKey == 'X')
{
......@@ -2341,7 +2339,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
ME_DisplayItem *para = cursor.pPara;
int from, to;
BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
if (wstr == '\t' &&
/* v4.1 allows tabs to be inserted with ctrl key down */
!(ctrl_is_down && !editor->bEmulateVersion10))
......@@ -2537,7 +2535,8 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
if (ME_IsSelection(editor))
{
int selStart, selEnd;
ME_GetSelection(editor, &selStart, &selEnd);
ME_GetSelectionOfs(editor, &selStart, &selEnd);
if (selStart <= offset && selEnd >= offset) {
ITextHost_TxSetCursor(editor->texthost,
LoadCursorW(NULL, (WCHAR*)IDC_ARROW),
......@@ -2566,7 +2565,7 @@ static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
int seltype = 0;
if(!editor->lpOleCallback || !editor->hWnd)
return FALSE;
ME_GetSelection(editor, &selrange.cpMin, &selrange.cpMax);
ME_GetSelectionOfs(editor, &selrange.cpMin, &selrange.cpMax);
if(selrange.cpMin == selrange.cpMax)
seltype |= SEL_EMPTY;
else
......@@ -3006,7 +3005,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
UINT from, to;
PUINT pfrom = wParam ? (PUINT)wParam : &from;
PUINT pto = lParam ? (PUINT)lParam : &to;
ME_GetSelection(editor, (int *)pfrom, (int *)pto);
ME_GetSelectionOfs(editor, (int *)pfrom, (int *)pto);
if ((*pfrom|*pto) & 0xFFFF0000)
return -1;
return MAKELONG(*pfrom,*pto);
......@@ -3014,7 +3013,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_EXGETSEL:
{
CHARRANGE *pRange = (CHARRANGE *)lParam;
ME_GetSelection(editor, &pRange->cpMin, &pRange->cpMax);
ME_GetSelectionOfs(editor, &pRange->cpMin, &pRange->cpMax);
TRACE("EM_EXGETSEL = (%d,%d)\n", pRange->cpMin, pRange->cpMax);
return 0;
}
......@@ -3210,7 +3209,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
bSelection = (pStruct->flags & ST_SELECTION) != 0;
if (bSelection) {
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to - from, FALSE);
} else {
......@@ -3320,11 +3319,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
} else if (editor->mode & TM_PLAINTEXT) {
return 0;
} else {
int from, to;
ME_GetSelection(editor, &from, &to);
bRepaint = (from != to);
bRepaint = ME_IsSelection(editor);
ME_SetSelectionCharFormat(editor, p);
if (from != to) editor->nModifyStep = 1;
if (bRepaint) editor->nModifyStep = 1;
}
ME_CommitUndo(editor);
if (bRepaint)
......@@ -3403,7 +3400,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case WM_CLEAR:
{
int from, to;
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
ME_InternalDeleteText(editor, from, to-from, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor);
......@@ -3417,7 +3414,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
size_t len = wszText ? lstrlenW(wszText) : 0;
TRACE("EM_REPLACESEL - %s\n", debugstr_w(wszText));
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to-from, FALSE);
ME_InsertTextFromCursor(editor, 0, wszText, len, style);
......@@ -3524,7 +3521,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case WM_COPY:
{
CHARRANGE range;
ME_GetSelection(editor, &range.cpMin, &range.cpMax);
ME_GetSelectionOfs(editor, &range.cpMin, &range.cpMax);
if (ME_Copy(editor, &range) && msg == WM_CUT)
{
......@@ -3560,7 +3557,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_GETSELTEXT:
{
int from, to;
ME_GetSelection(editor, &from, &to);
ME_GetSelectionOfs(editor, &from, &to);
return ME_GetTextRange(editor, (WCHAR *)lParam, from,
to - from, unicode);
}
......
......@@ -167,7 +167,8 @@ void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl);
int ME_GetCursorOfs(const ME_Cursor *cursor);
void ME_GetSelection(ME_TextEditor *editor, int *from, int *to);
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to);
int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to);
int ME_CountParagraphsBetween(ME_TextEditor *editor, int from, int to);
BOOL ME_IsSelection(ME_TextEditor *editor);
void ME_DeleteSelection(ME_TextEditor *editor);
......
......@@ -413,7 +413,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
return;
start = ME_FindItemBack(rundi, diStartRow);
ME_GetSelection(c->editor, &nSelFrom, &nSelTo);
ME_GetSelectionOfs(c->editor, &nSelFrom, &nSelTo);
/* Draw selected end-of-paragraph mark */
if (run->nFlags & MERF_ENDPARA)
......@@ -1308,7 +1308,7 @@ ME_InvalidateSelection(ME_TextEditor *editor)
int nStart, nEnd;
int len = ME_GetTextLength(editor);
ME_GetSelection(editor, &nStart, &nEnd);
ME_GetSelectionOfs(editor, &nStart, &nEnd);
/* if both old and new selection are 0-char (= caret only), then
there's no (inverted) area to be repainted, neither old nor new */
if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd)
......@@ -1341,7 +1341,7 @@ ME_InvalidateSelection(ME_TextEditor *editor)
ME_InvalidateMarkedParagraphs(editor);
/* remember the last invalidated position */
ME_GetSelection(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
ME_GetSelectionOfs(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara);
assert(editor->pLastSelStartPara->type == diParagraph);
assert(editor->pLastSelEndPara->type == diParagraph);
......
......@@ -321,7 +321,7 @@ IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
if(!lplpdataobj)
return E_INVALIDARG;
if(!lpchrg) {
ME_GetSelection(This->editor, &tmpchrg.cpMin, &tmpchrg.cpMax);
ME_GetSelectionOfs(This->editor, &tmpchrg.cpMin, &tmpchrg.cpMax);
lpchrg = &tmpchrg;
}
return ME_GetDataObject(This->editor, lpchrg, lplpdataobj);
......
......@@ -733,7 +733,7 @@ void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Ru
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelection(editor, &nFrom, &nTo);
ME_GetSelectionOfs(editor, &nFrom, &nTo);
if (nFrom == nTo)
{
ME_Style *s;
......@@ -849,7 +849,7 @@ void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelection(editor, &nFrom, &nTo);
ME_GetSelectionOfs(editor, &nFrom, &nTo);
if (nFrom == nTo && editor->pBuffer->pCharStyle)
{
ME_CopyCharFormat(pFmt, &editor->pBuffer->pCharStyle->fmt);
......
......@@ -467,16 +467,15 @@ void ME_ReleaseStyle(ME_Style *s)
ME_DestroyStyle(s);
}
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) {
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor)
{
if (ME_IsSelection(editor))
{
ME_Cursor c;
int from, to;
ME_Cursor *from, *to;
ME_GetSelection(editor, &from, &to);
ME_CursorFromCharOfs(editor, from, &c);
ME_AddRefStyle(c.pRun->member.run.style);
return c.pRun->member.run.style;
ME_AddRefStyle(from->pRun->member.run.style);
return from->pRun->member.run.style;
}
if (editor->pBuffer->pCharStyle) {
ME_AddRefStyle(editor->pBuffer->pCharStyle);
......
......@@ -1001,7 +1001,7 @@ ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
int nStart, nTo;
if (dwFormat & SFF_SELECTION)
ME_GetSelection(editor, &nStart, &nTo);
ME_GetSelectionOfs(editor, &nStart, &nTo);
else {
nStart = 0;
nTo = -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment