ReactOS 0.4.15-dev-7942-gd23573b
caret.c File Reference
#include "editor.h"
Include dependency graph for caret.c:

Go to the source code of this file.

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (richedit)
 
void ME_SetCursorToStart (ME_TextEditor *editor, ME_Cursor *cursor)
 
static void ME_SetCursorToEnd (ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop)
 
int ME_GetSelectionOfs (ME_TextEditor *editor, int *from, int *to)
 
int ME_GetSelection (ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to)
 
int ME_GetTextLength (ME_TextEditor *editor)
 
int ME_GetTextLengthEx (ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
 
int set_selection_cursors (ME_TextEditor *editor, int from, int to)
 
void ME_GetCursorCoordinates (ME_TextEditor *editor, ME_Cursor *pCursor, int *x, int *y, int *height)
 
void create_caret (ME_TextEditor *editor)
 
void show_caret (ME_TextEditor *editor)
 
void hide_caret (ME_TextEditor *editor)
 
void update_caret (ME_TextEditor *editor)
 
BOOL ME_InternalDeleteText (ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce)
 
BOOL ME_DeleteTextAtCursor (ME_TextEditor *editor, int nCursor, int nChars)
 
static ME_DisplayItemME_InternalInsertTextFromCursor (ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style, int flags)
 
static struct re_objectcreate_re_object (const REOBJECT *reo)
 
void ME_InsertOLEFromCursor (ME_TextEditor *editor, const REOBJECT *reo, int nCursor)
 
void ME_InsertEndRowFromCursor (ME_TextEditor *editor, int nCursor)
 
void ME_InsertTextFromCursor (ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style)
 
int ME_MoveCursorChars (ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
 
BOOL ME_MoveCursorWords (ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
 
static void ME_SelectByType (ME_TextEditor *editor, ME_SelectionType selectionType)
 
int ME_GetCursorOfs (const ME_Cursor *cursor)
 
static ME_DisplayItemME_FindPixelPosInTableRow (int x, int y, ME_DisplayItem *para)
 
static BOOL ME_FindRunInRow (ME_TextEditor *editor, ME_DisplayItem *pRow, int x, ME_Cursor *cursor, BOOL *pbCaretAtEnd)
 
static BOOL ME_FindPixelPos (ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol, BOOL final_eop)
 
BOOL ME_CharFromPos (ME_TextEditor *editor, int x, int y, ME_Cursor *cursor, BOOL *isExact)
 
static void ME_ExtendAnchorSelection (ME_TextEditor *editor)
 
void ME_LButtonDown (ME_TextEditor *editor, int x, int y, int clickNum)
 
void ME_MouseMove (ME_TextEditor *editor, int x, int y)
 
static int ME_GetXForArrow (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_MoveCursorLines (ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL extend)
 
static void ME_ArrowPageUp (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_ArrowPageDown (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_ArrowHome (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_ArrowCtrlHome (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_ArrowEnd (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_ArrowCtrlEnd (ME_TextEditor *editor, ME_Cursor *pCursor)
 
BOOL ME_IsSelection (ME_TextEditor *editor)
 
void ME_DeleteSelection (ME_TextEditor *editor)
 
ME_StyleME_GetSelectionInsertStyle (ME_TextEditor *editor)
 
void ME_SendSelChange (ME_TextEditor *editor)
 
BOOL ME_ArrowKey (ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
 

Function Documentation

◆ create_caret()

void create_caret ( ME_TextEditor editor)

Definition at line 272 of file caret.c.

273{
274 int x, y, height;
275
276 ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height);
278 editor->caret_height = height;
279 editor->caret_hidden = TRUE;
280}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, int *x, int *y, int *height)
Definition: caret.c:221
#define ITextHost_TxCreateCaret(This, a, b, c)
Definition: editor.h:295
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
ITextHost * texthost
Definition: editstr.h:383
ME_Cursor * pCursors
Definition: editstr.h:387
BOOL caret_hidden
Definition: editstr.h:444

Referenced by ME_HandleMessage(), and update_caret().

◆ create_re_object()

static struct re_object * create_re_object ( const REOBJECT reo)
static

Definition at line 533 of file caret.c.

534{
535 struct re_object *reobj = heap_alloc(sizeof(*reobj));
536
537 if (!reobj)
538 {
539 WARN("Fail to allocate re_object.\n");
540 return NULL;
541 }
542 ME_CopyReObject(&reobj->obj, reo, REO_GETOBJ_ALL_INTERFACES);
543 return reobj;
544}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
#define WARN(fmt,...)
Definition: debug.h:112
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN
Definition: richole.c:5907
REOBJECT obj
Definition: editstr.h:155

Referenced by ME_InsertOLEFromCursor().

◆ hide_caret()

void hide_caret ( ME_TextEditor editor)

Definition at line 288 of file caret.c.

289{
290 /* calls to HideCaret are cumulative; do so only once */
291 if (!editor->caret_hidden)
292 {
294 editor->caret_hidden = TRUE;
295 }
296}
#define FALSE
Definition: types.h:117
#define ITextHost_TxShowCaret(This, a)
Definition: editor.h:296

Referenced by ME_ArrowKey(), ME_HandleMessage(), and update_caret().

◆ ME_ArrowCtrlEnd()

static void ME_ArrowCtrlEnd ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1572 of file caret.c.

1573{
1574 ME_SetCursorToEnd(editor, pCursor, FALSE);
1575 editor->bCaretAtEnd = FALSE;
1576}
static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop)
Definition: caret.c:34
BOOL bCaretAtEnd
Definition: editstr.h:399

Referenced by ME_ArrowKey().

◆ ME_ArrowCtrlHome()

static void ME_ArrowCtrlHome ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1541 of file caret.c.

1542{
1543 ME_SetCursorToStart(editor, pCursor);
1544 editor->bCaretAtEnd = FALSE;
1545}
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27

Referenced by ME_ArrowKey().

◆ ME_ArrowEnd()

static void ME_ArrowEnd ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1547 of file caret.c.

1548{
1549 ME_DisplayItem *pRow;
1550
1551 if (editor->bCaretAtEnd && !pCursor->nOffset)
1552 return;
1553
1555 assert(pRow);
1556 if (pRow->type == diStartRow) {
1557 ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun);
1558 assert(pRun);
1559 pCursor->pRun = pRun;
1560 assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun));
1561 pCursor->nOffset = 0;
1562 editor->bCaretAtEnd = TRUE;
1563 return;
1564 }
1565 pCursor->pRun = ME_FindItemBack(pRow, diRun);
1566 assert(pCursor->pRun && pCursor->pRun->member.run.nFlags & MERF_ENDPARA);
1567 assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun));
1568 pCursor->nOffset = 0;
1569 editor->bCaretAtEnd = FALSE;
1570}
#define assert(x)
Definition: debug.h:53
ME_DisplayItem * ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:111
ME_DisplayItem * ME_GetParagraph(ME_DisplayItem *run) DECLSPEC_HIDDEN
Definition: para.c:815
ME_DisplayItem * ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:134
#define MERF_ENDPARA
Definition: editstr.h:122
@ diStartRow
Definition: editstr.h:88
@ diRun
Definition: editstr.h:87
@ diStartRowOrParagraphOrEnd
Definition: editstr.h:93
ME_DisplayItem * pPara
Definition: editstr.h:275
int nOffset
Definition: editstr.h:277
ME_DisplayItem * pRun
Definition: editstr.h:276
union tagME_DisplayItem::@536 member
ME_DIType type
Definition: editstr.h:256
int nFlags
Definition: editstr.h:165

Referenced by ME_ArrowKey().

◆ ME_ArrowHome()

static void ME_ArrowHome ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1521 of file caret.c.

1522{
1523 ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
1524 if (pRow) {
1525 ME_DisplayItem *pRun;
1526 if (editor->bCaretAtEnd && !pCursor->nOffset) {
1527 pRow = ME_FindItemBack(pRow, diStartRow);
1528 if (!pRow)
1529 return;
1530 }
1531 pRun = ME_FindItemFwd(pRow, diRun);
1532 if (pRun) {
1533 pCursor->pRun = pRun;
1534 assert(pCursor->pPara == ME_GetParagraph(pRun));
1535 pCursor->nOffset = 0;
1536 }
1537 }
1538 editor->bCaretAtEnd = FALSE;
1539}

Referenced by ME_ArrowKey().

◆ ME_ArrowKey()

BOOL ME_ArrowKey ( ME_TextEditor editor,
int  nVKey,
BOOL  extend,
BOOL  ctrl 
)

Definition at line 1630 of file caret.c.

1631{
1632 int nCursor = 0;
1633 ME_Cursor *p = &editor->pCursors[nCursor];
1634 ME_Cursor tmp_curs = *p;
1635 BOOL success = FALSE;
1636
1637 ME_CheckCharOffsets(editor);
1638 switch(nVKey) {
1639 case VK_LEFT:
1640 editor->bCaretAtEnd = FALSE;
1641 if (ctrl)
1642 success = ME_MoveCursorWords(editor, &tmp_curs, -1);
1643 else
1644 success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend);
1645 break;
1646 case VK_RIGHT:
1647 editor->bCaretAtEnd = FALSE;
1648 if (ctrl)
1649 success = ME_MoveCursorWords(editor, &tmp_curs, +1);
1650 else
1651 success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend);
1652 break;
1653 case VK_UP:
1654 ME_MoveCursorLines(editor, &tmp_curs, -1, extend);
1655 break;
1656 case VK_DOWN:
1657 ME_MoveCursorLines(editor, &tmp_curs, +1, extend);
1658 break;
1659 case VK_PRIOR:
1660 ME_ArrowPageUp(editor, &tmp_curs);
1661 break;
1662 case VK_NEXT:
1663 ME_ArrowPageDown(editor, &tmp_curs);
1664 break;
1665 case VK_HOME: {
1666 if (ctrl)
1667 ME_ArrowCtrlHome(editor, &tmp_curs);
1668 else
1669 ME_ArrowHome(editor, &tmp_curs);
1670 editor->bCaretAtEnd = FALSE;
1671 break;
1672 }
1673 case VK_END:
1674 if (ctrl)
1675 ME_ArrowCtrlEnd(editor, &tmp_curs);
1676 else
1677 ME_ArrowEnd(editor, &tmp_curs);
1678 break;
1679 }
1680
1681 if (!extend)
1682 editor->pCursors[1] = tmp_curs;
1683 *p = tmp_curs;
1684
1685 ME_InvalidateSelection(editor);
1686 ME_Repaint(editor);
1687 hide_caret(editor);
1688 ME_EnsureVisible(editor, &tmp_curs);
1689 update_caret(editor);
1690 ME_SendSelChange(editor);
1691 return success;
1692}
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1521
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:720
BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
Definition: caret.c:799
static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1409
static void ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL extend)
Definition: caret.c:1323
void hide_caret(ME_TextEditor *editor)
Definition: caret.c:288
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1572
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1598
static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1463
static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1547
void update_caret(ME_TextEditor *editor)
Definition: caret.c:298
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1541
void ME_CheckCharOffsets(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: run.c:101
void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor) DECLSPEC_HIDDEN
Definition: paint.c:1275
void ME_InvalidateSelection(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:1322
void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:106
unsigned int BOOL
Definition: ntddk_ex.h:94
GLfloat GLfloat p
Definition: glext.h:8902
#define ctrl
Definition: input.c:1756
#define success(from, fromstr, to, tostr)
#define VK_UP
Definition: winuser.h:2225
#define VK_NEXT
Definition: winuser.h:2221
#define VK_END
Definition: winuser.h:2222
#define VK_HOME
Definition: winuser.h:2223
#define VK_LEFT
Definition: winuser.h:2224
#define VK_RIGHT
Definition: winuser.h:2226
#define VK_DOWN
Definition: winuser.h:2227
#define VK_PRIOR
Definition: winuser.h:2220

Referenced by ME_KeyDown().

◆ ME_ArrowPageDown()

static void ME_ArrowPageDown ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1463 of file caret.c.

1464{
1465 ME_DisplayItem *pLast;
1466 int x, y;
1467
1468 /* Find y position of the last row */
1469 pLast = editor->pBuffer->pLast;
1470 y = pLast->member.para.prev_para->member.para.pt.y
1472
1473 x = ME_GetXForArrow(editor, pCursor);
1474
1475 if (editor->vert_si.nPos >= y - editor->sizeWindow.cy)
1476 {
1477 ME_SetCursorToEnd(editor, pCursor, FALSE);
1478 editor->bCaretAtEnd = FALSE;
1479 } else {
1480 ME_DisplayItem *pRun = pCursor->pRun;
1482 int yd, yp;
1483 int yOldScrollPos = editor->vert_si.nPos;
1484
1485 if (!pCursor->nOffset && editor->bCaretAtEnd)
1486 pRun = ME_FindItemBack(pRun, diRun);
1487
1489 assert(p->type == diStartRow);
1491 y = yp + p->member.row.pt.y;
1492
1493 /* For native richedit controls:
1494 * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us
1495 * v4.1 can scroll past this position here. */
1496 ME_ScrollDown(editor, editor->sizeWindow.cy);
1497 /* Only move the cursor by the amount scrolled. */
1498 yd = y + editor->vert_si.nPos - yOldScrollPos;
1499 pLast = p;
1500
1501 do {
1503 if (!p)
1504 break;
1505 if (p->type == diParagraph) {
1506 yp = p->member.para.pt.y;
1507 continue;
1508 }
1509 y = yp + p->member.row.pt.y;
1510 if (y >= yd)
1511 break;
1512 pLast = p;
1513 } while(1);
1514
1515 ME_FindRunInRow(editor, pLast, x, pCursor, &editor->bCaretAtEnd);
1516 }
1517 assert(pCursor->pRun);
1518 assert(pCursor->pRun->type == diRun);
1519}
static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1298
static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, int x, ME_Cursor *cursor, BOOL *pbCaretAtEnd)
Definition: caret.c:1002
void ME_ScrollDown(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN
Definition: paint.c:1121
@ diStartRowOrParagraph
Definition: editstr.h:92
@ diParagraph
Definition: editstr.h:85
LONG cy
Definition: kdterminal.h:28
ME_Paragraph para
Definition: editstr.h:262
struct tagME_DisplayItem * prev_para
Definition: editstr.h:217
POINT pt
Definition: editstr.h:239
ME_DisplayItem * pLast
Definition: editstr.h:268
SCROLLINFO vert_si
Definition: editstr.h:441
ME_TextBuffer * pBuffer
Definition: editstr.h:386
long y
Definition: polytest.cpp:48

Referenced by ME_ArrowKey().

◆ ME_ArrowPageUp()

static void ME_ArrowPageUp ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1409 of file caret.c.

1410{
1412
1413 if (editor->vert_si.nPos < p->member.row.nHeight)
1414 {
1415 ME_SetCursorToStart(editor, pCursor);
1416 editor->bCaretAtEnd = FALSE;
1417 /* Native clears seems to clear this x value on page up at the top
1418 * of the text, but not on page down at the end of the text.
1419 * Doesn't make sense, but we try to be bug for bug compatible. */
1420 editor->nUDArrowX = -1;
1421 } else {
1422 ME_DisplayItem *pRun = pCursor->pRun;
1423 ME_DisplayItem *pLast;
1424 int x, y, yd, yp;
1425 int yOldScrollPos = editor->vert_si.nPos;
1426
1427 x = ME_GetXForArrow(editor, pCursor);
1428 if (!pCursor->nOffset && editor->bCaretAtEnd)
1429 pRun = ME_FindItemBack(pRun, diRun);
1430
1432 assert(p->type == diStartRow);
1434 y = yp + p->member.row.pt.y;
1435
1436 ME_ScrollUp(editor, editor->sizeWindow.cy);
1437 /* Only move the cursor by the amount scrolled. */
1438 yd = y + editor->vert_si.nPos - yOldScrollPos;
1439 pLast = p;
1440
1441 do {
1443 if (!p)
1444 break;
1445 if (p->type == diParagraph) { /* crossing paragraphs */
1446 if (p->member.para.prev_para == NULL)
1447 break;
1448 yp = p->member.para.prev_para->member.para.pt.y;
1449 continue;
1450 }
1451 y = yp + p->member.row.pt.y;
1452 if (y < yd)
1453 break;
1454 pLast = p;
1455 } while(1);
1456
1457 ME_FindRunInRow(editor, pLast, x, pCursor, &editor->bCaretAtEnd);
1458 }
1459 assert(pCursor->pRun);
1460 assert(pCursor->pRun->type == diRun);
1461}
void ME_ScrollUp(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN
Definition: paint.c:1116
ME_DisplayItem * pFirst
Definition: editstr.h:268

Referenced by ME_ArrowKey().

◆ ME_CharFromPos()

BOOL ME_CharFromPos ( ME_TextEditor editor,
int  x,
int  y,
ME_Cursor cursor,
BOOL isExact 
)

Definition at line 1122 of file caret.c.

1124{
1125 RECT rc;
1126 BOOL bResult;
1127
1128 ITextHost_TxGetClientRect(editor->texthost, &rc);
1129 if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom) {
1130 if (isExact) *isExact = FALSE;
1131 return FALSE;
1132 }
1133 x += editor->horz_si.nPos;
1134 y += editor->vert_si.nPos;
1135 bResult = ME_FindPixelPos(editor, x, y, cursor, NULL, FALSE);
1136 if (isExact) *isExact = bResult;
1137 return TRUE;
1138}
static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol, BOOL final_eop)
Definition: caret.c:1055
#define ITextHost_TxGetClientRect(This, a)
Definition: editor.h:308
const char cursor[]
Definition: icontest.c:13
SCROLLINFO horz_si
Definition: editstr.h:441
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309

Referenced by ME_HandleMessage(), ME_LinkNotify(), and ME_SetCursor().

◆ ME_DeleteSelection()

void ME_DeleteSelection ( ME_TextEditor editor)

Definition at line 1584 of file caret.c.

1585{
1586 int from, to;
1587 int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
1588 int nEndCursor = nStartCursor ^ 1;
1589 ME_DeleteTextAtCursor(editor, nStartCursor, to - from);
1590 editor->pCursors[nEndCursor] = editor->pCursors[nStartCursor];
1591}
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
Definition: caret.c:510
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
Definition: caret.c:42
CardRegion * from
Definition: spigame.cpp:19

Referenced by ME_HandleMessage(), ME_InsertEndRowFromCursor(), ME_InsertOLEFromCursor(), ME_InsertTextFromCursor(), and ME_KeyDown().

◆ ME_DeleteTextAtCursor()

BOOL ME_DeleteTextAtCursor ( ME_TextEditor editor,
int  nCursor,
int  nChars 
)

Definition at line 510 of file caret.c.

511{
512 assert(nCursor>=0 && nCursor<editor->nCursors);
513 /* text operations set modified state */
514 editor->nModifyStep = 1;
515 return ME_InternalDeleteText(editor, &editor->pCursors[nCursor],
516 nChars, FALSE);
517}
BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce)
Definition: caret.c:360

Referenced by ME_DeleteSelection(), and ME_KeyDown().

◆ ME_ExtendAnchorSelection()

static void ME_ExtendAnchorSelection ( ME_TextEditor editor)
static

Definition at line 1152 of file caret.c.

1153{
1154 ME_Cursor tmp_cursor;
1155 int curOfs, anchorStartOfs, anchorEndOfs;
1156 if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument)
1157 return;
1158 curOfs = ME_GetCursorOfs(&editor->pCursors[0]);
1159 anchorStartOfs = ME_GetCursorOfs(&editor->pCursors[3]);
1160 anchorEndOfs = ME_GetCursorOfs(&editor->pCursors[2]);
1161
1162 tmp_cursor = editor->pCursors[0];
1163 editor->pCursors[0] = editor->pCursors[2];
1164 editor->pCursors[1] = editor->pCursors[3];
1165 if (curOfs < anchorStartOfs)
1166 {
1167 /* Extend the left side of selection */
1168 editor->pCursors[1] = tmp_cursor;
1169 if (editor->nSelectionType == stWord)
1170 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
1171 else
1172 {
1173 ME_DisplayItem *pItem;
1174 ME_DIType searchType = ((editor->nSelectionType == stLine) ?
1176 pItem = ME_FindItemBack(editor->pCursors[1].pRun, searchType);
1177 editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun);
1178 editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun);
1179 editor->pCursors[1].nOffset = 0;
1180 }
1181 }
1182 else if (curOfs >= anchorEndOfs)
1183 {
1184 /* Extend the right side of selection */
1185 editor->pCursors[0] = tmp_cursor;
1186 if (editor->nSelectionType == stWord)
1187 ME_MoveCursorWords(editor, &editor->pCursors[0], +1);
1188 else
1189 {
1190 ME_DisplayItem *pItem;
1191 ME_DIType searchType = ((editor->nSelectionType == stLine) ?
1193 pItem = ME_FindItemFwd(editor->pCursors[0].pRun, searchType);
1194 if (pItem->type == diTextEnd)
1195 editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun);
1196 else
1197 editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun);
1198 editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun);
1199 editor->pCursors[0].nOffset = 0;
1200 }
1201 }
1202}
int ME_GetCursorOfs(const ME_Cursor *cursor)
Definition: caret.c:957
ME_DIType
Definition: editstr.h:82
@ diTextEnd
Definition: editstr.h:89
@ diParagraphOrEnd
Definition: editstr.h:96
@ stWord
Definition: editstr.h:358
@ stPosition
Definition: editstr.h:357
@ stLine
Definition: editstr.h:359
@ stDocument
Definition: editstr.h:361
ME_SelectionType nSelectionType
Definition: editstr.h:434

Referenced by ME_LButtonDown(), and ME_MouseMove().

◆ ME_FindPixelPos()

static BOOL ME_FindPixelPos ( ME_TextEditor editor,
int  x,
int  y,
ME_Cursor result,
BOOL is_eol,
BOOL  final_eop 
)
static

Definition at line 1055 of file caret.c.

1057{
1059 BOOL isExact = TRUE;
1060
1061 x -= editor->rcFormat.left;
1062 y -= editor->rcFormat.top;
1063
1064 if (is_eol)
1065 *is_eol = FALSE;
1066
1067 /* find paragraph */
1068 for (; p != editor->pBuffer->pLast; p = p->member.para.next_para)
1069 {
1070 assert(p->type == diParagraph);
1071 if (y < p->member.para.pt.y + p->member.para.nHeight)
1072 {
1073 if (p->member.para.nFlags & MEPF_ROWSTART)
1075 y -= p->member.para.pt.y;
1077 break;
1078 } else if (p->member.para.nFlags & MEPF_ROWSTART) {
1080 }
1081 }
1082 /* find row */
1083 for (; p != editor->pBuffer->pLast; )
1084 {
1085 ME_DisplayItem *pp;
1086 assert(p->type == diStartRow);
1087 if (y < p->member.row.pt.y + p->member.row.nHeight) break;
1089 if (!pp) break;
1090 p = pp;
1091 }
1092 if (p == editor->pBuffer->pLast && !final_eop)
1093 {
1094 /* The position is below the last paragraph, so the last row will be used
1095 * rather than the end of the text, so the x position will be used to
1096 * determine the offset closest to the pixel position. */
1097 isExact = FALSE;
1099 if (!p) p = editor->pBuffer->pLast;
1100 }
1101
1102 assert( p->type == diStartRow || p == editor->pBuffer->pLast );
1103
1104 if( p->type == diStartRow )
1105 return ME_FindRunInRow( editor, p, x, result, is_eol ) && isExact;
1106
1107 ME_SetCursorToEnd(editor, result, TRUE);
1108 return FALSE;
1109}
static ME_DisplayItem * ME_FindPixelPosInTableRow(int x, int y, ME_DisplayItem *para)
Definition: caret.c:964
ME_DisplayItem * ME_GetTableRowEnd(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:136
#define MEPF_ROWSTART
Definition: editstr.h:144
GLuint64EXT * result
Definition: glext.h:11304
static __inline int is_eol(struct parser *parser, const CHAR *ptr)
Definition: inffile.c:422
struct tagME_DisplayItem * next_para
Definition: editstr.h:217
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306

Referenced by ME_CharFromPos(), ME_LButtonDown(), and ME_MouseMove().

◆ ME_FindPixelPosInTableRow()

static ME_DisplayItem * ME_FindPixelPosInTableRow ( int  x,
int  y,
ME_DisplayItem para 
)
static

Definition at line 964 of file caret.c.

966{
967 ME_DisplayItem *cell, *next_cell;
969 cell = para->member.para.next_para->member.para.pCell;
970 assert(cell);
971
972 /* find the cell we are in */
973 while ((next_cell = cell->member.cell.next_cell) != NULL) {
974 if (x < next_cell->member.cell.pt.x)
975 {
976 para = ME_FindItemFwd(cell, diParagraph);
977 /* Found the cell, but there might be multiple paragraphs in
978 * the cell, so need to search down the cell for the paragraph. */
979 while (cell == para->member.para.pCell) {
980 if (y < para->member.para.pt.y + para->member.para.nHeight)
981 {
982 if (para->member.para.nFlags & MEPF_ROWSTART)
983 return ME_FindPixelPosInTableRow(x, y, para);
984 else
985 return para;
986 }
987 para = para->member.para.next_para;
988 }
989 /* Past the end of the cell, so go back to the last cell paragraph */
990 return para->member.para.prev_para;
991 }
992 cell = next_cell;
993 }
994 /* Return table row delimiter */
995 para = ME_FindItemFwd(cell, diParagraph);
999 return para;
1000}
#define MEPF_ROWEND
Definition: editstr.h:145
#define PFM_TABLEROWDELIMITER
Definition: richedit.h:868
#define PFE_TABLEROWDELIMITER
Definition: richedit.h:942
DWORD dwMask
Definition: richedit.h:667
WORD wEffects
Definition: richedit.h:669
struct tagME_DisplayItem * next_cell
Definition: editstr.h:229
ME_Cell cell
Definition: editstr.h:261
PARAFORMAT2 fmt
Definition: editstr.h:204
struct tagME_DisplayItem * pCell
Definition: editstr.h:207

Referenced by ME_FindPixelPos(), and ME_FindPixelPosInTableRow().

◆ ME_FindRunInRow()

static BOOL ME_FindRunInRow ( ME_TextEditor editor,
ME_DisplayItem pRow,
int  x,
ME_Cursor cursor,
BOOL pbCaretAtEnd 
)
static

Definition at line 1002 of file caret.c.

1004{
1005 ME_DisplayItem *pNext, *pLastRun;
1006 ME_Row *row = &pRow->member.row;
1007 BOOL exact = TRUE;
1008
1009 if (x < row->pt.x)
1010 {
1011 x = row->pt.x;
1012 exact = FALSE;
1013 }
1014 pNext = ME_FindItemFwd(pRow, diRunOrStartRow);
1015 assert(pNext->type == diRun);
1016 if (pbCaretAtEnd) *pbCaretAtEnd = FALSE;
1017 cursor->nOffset = 0;
1018 do {
1019 int run_x = pNext->member.run.pt.x;
1020 int width = pNext->member.run.nWidth;
1021
1022 if (x >= run_x && x < run_x+width)
1023 {
1024 cursor->nOffset = ME_CharFromPoint(editor, x-run_x, &pNext->member.run, TRUE, TRUE);
1025 cursor->pRun = pNext;
1026 cursor->pPara = ME_GetParagraph( cursor->pRun );
1027 return exact;
1028 }
1029 pLastRun = pNext;
1030 pNext = ME_FindItemFwd(pNext, diRunOrStartRow);
1031 } while(pNext && pNext->type == diRun);
1032
1033 if ((pLastRun->member.run.nFlags & MERF_ENDPARA) == 0)
1034 {
1035 cursor->pRun = ME_FindItemFwd(pNext, diRun);
1036 if (pbCaretAtEnd) *pbCaretAtEnd = TRUE;
1037 }
1038 else
1039 cursor->pRun = pLastRun;
1040
1041 cursor->pPara = ME_GetParagraph( cursor->pRun );
1042 return FALSE;
1043}
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define pt(x, y)
Definition: drawing.c:79
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:521
@ diRunOrStartRow
Definition: editstr.h:95
GLint GLint GLsizei width
Definition: gl.h:1546
POINT pt
Definition: editstr.h:167
int nWidth
Definition: editstr.h:164
long x
Definition: polytest.cpp:48

Referenced by ME_ArrowPageDown(), ME_ArrowPageUp(), ME_FindPixelPos(), and ME_MoveCursorLines().

◆ ME_GetCursorCoordinates()

void ME_GetCursorCoordinates ( ME_TextEditor editor,
ME_Cursor pCursor,
int x,
int y,
int height 
)

Definition at line 221 of file caret.c.

223{
225 ME_DisplayItem *run = pCursor->pRun;
226 ME_DisplayItem *para = pCursor->pPara;
227 ME_DisplayItem *pSizeRun = run;
229 int run_x;
230
231 assert(height && x && y);
233 assert(run && run->type == diRun);
234 assert(para && para->type == diParagraph);
235
237 assert(row && row->type == diStartRow);
238
239 ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
240
241 if (!pCursor->nOffset)
242 {
244 assert(prev);
245 if (prev->type == diRun)
246 pSizeRun = prev;
247 }
248 if (editor->bCaretAtEnd && !pCursor->nOffset &&
249 run == ME_FindItemFwd(row, diRun))
250 {
252 assert(tmp);
253 if (tmp->type == diRun)
254 {
256 pSizeRun = run = tmp;
257 assert(run);
258 assert(run->type == diRun);
259 }
260 }
261 run_x = ME_PointFromCharContext( &c, &run->member.run, pCursor->nOffset, TRUE );
262
263 *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
264 *x = c.rcView.left + run->member.run.pt.x + run_x - editor->horz_si.nPos;
265 *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
266 + run->member.run.pt.y - pSizeRun->member.run.nAscent
267 - editor->vert_si.nPos;
269 return;
270}
void ME_DestroyContext(ME_Context *c)
Definition: context.c:44
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
Definition: context.c:23
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:557
#define ITextHost_TxGetDC(This)
Definition: editor.h:287
@ diRunOrParagraph
Definition: editstr.h:94
#define MEPF_REWRAP
Definition: editstr.h:141
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
int nAscent
Definition: editstr.h:166
int nDescent
Definition: editstr.h:166

Referenced by create_caret(), ITextRange_fnScrollIntoView(), and update_caret().

◆ ME_GetCursorOfs()

◆ ME_GetSelection()

int ME_GetSelection ( ME_TextEditor editor,
ME_Cursor **  from,
ME_Cursor **  to 
)

Definition at line 57 of file caret.c.

58{
59 int from_ofs = ME_GetCursorOfs( &editor->pCursors[0] );
60 int to_ofs = ME_GetCursorOfs( &editor->pCursors[1] );
61 BOOL swap = (from_ofs > to_ofs);
62
63 if (from_ofs == to_ofs)
64 {
65 /* If cursor[0] is at the beginning of a run and cursor[1] at the end
66 of the prev run then we need to swap. */
67 if (editor->pCursors[0].nOffset < editor->pCursors[1].nOffset)
68 swap = TRUE;
69 }
70
71 if (!swap)
72 {
73 *from = &editor->pCursors[0];
74 *to = &editor->pCursors[1];
75 return 0;
76 } else {
77 *from = &editor->pCursors[1];
78 *to = &editor->pCursors[0];
79 return 1;
80 }
81}
#define swap(a, b)
Definition: qsort.c:63

Referenced by IRichEditOle_fnGetObject(), ITextSelection_fnGetChar(), ITextSelection_fnGetText(), ME_GetInsertStyle(), ME_GetSelectionCharFormat(), ME_SetSelectionCharFormat(), ME_StreamIn(), and ME_UpdateSelectionLinkAttribute().

◆ ME_GetSelectionInsertStyle()

ME_Style * ME_GetSelectionInsertStyle ( ME_TextEditor editor)

Definition at line 1593 of file caret.c.

1594{
1595 return ME_GetInsertStyle(editor, 0);
1596}
ME_Style * ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN
Definition: style.c:476

Referenced by ME_HandleMessage(), ME_ReplaceSel(), and ME_StreamIn().

◆ ME_GetSelectionOfs()

◆ ME_GetTextLength()

◆ ME_GetTextLengthEx()

int ME_GetTextLengthEx ( ME_TextEditor editor,
const GETTEXTLENGTHEX how 
)

Definition at line 91 of file caret.c.

92{
93 int length;
94
95 if (how->flags & GTL_PRECISE && how->flags & GTL_CLOSE)
96 return E_INVALIDARG;
97 if (how->flags & GTL_NUMCHARS && how->flags & GTL_NUMBYTES)
98 return E_INVALIDARG;
99
100 length = ME_GetTextLength(editor);
101
102 if ((editor->styleFlags & ES_MULTILINE)
103 && (how->flags & GTL_USECRLF)
104 && !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */
105 length += editor->nParagraphs - 1;
106
107 if (how->flags & GTL_NUMBYTES ||
108 (how->flags & GTL_PRECISE && /* GTL_PRECISE seems to imply GTL_NUMBYTES */
109 !(how->flags & GTL_NUMCHARS))) /* unless GTL_NUMCHARS is given */
110 {
111 CPINFO cpinfo;
112
113 if (how->codepage == 1200)
114 return length * 2;
115 if (how->flags & GTL_PRECISE)
116 FIXME("GTL_PRECISE flag unsupported. Using GTL_CLOSE\n");
117 if (GetCPInfo(how->codepage, &cpinfo))
118 return length * cpinfo.MaxCharSize;
119 ERR("Invalid codepage %u\n", how->codepage);
120 return E_INVALIDARG;
121 }
122 return length;
123}
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:2039
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define ES_MULTILINE
Definition: pedump.c:667
#define GTL_CLOSE
Definition: richedit.h:1057
#define GTL_NUMCHARS
Definition: richedit.h:1058
#define GTL_PRECISE
Definition: richedit.h:1056
#define GTL_NUMBYTES
Definition: richedit.h:1059
#define GTL_USECRLF
Definition: richedit.h:1055
UINT MaxCharSize
Definition: winnls.h:581
DWORD styleFlags
Definition: editstr.h:388
BOOL bEmulateVersion10
Definition: editstr.h:385

Referenced by ME_HandleMessage().

◆ ME_GetXForArrow()

static int ME_GetXForArrow ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1298 of file caret.c.

1299{
1300 ME_DisplayItem *pRun = pCursor->pRun;
1301 int x;
1302
1303 if (editor->nUDArrowX != -1)
1304 x = editor->nUDArrowX;
1305 else {
1306 if (editor->bCaretAtEnd)
1307 {
1308 pRun = ME_FindItemBack(pRun, diRun);
1309 assert(pRun);
1310 x = pRun->member.run.pt.x + pRun->member.run.nWidth;
1311 }
1312 else {
1313 x = pRun->member.run.pt.x;
1314 x += ME_PointFromChar(editor, &pRun->member.run, pCursor->nOffset, TRUE);
1315 }
1316 editor->nUDArrowX = x;
1317 }
1318 return x;
1319}
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:598

Referenced by ME_ArrowPageDown(), ME_ArrowPageUp(), and ME_MoveCursorLines().

◆ ME_InsertEndRowFromCursor()

void ME_InsertEndRowFromCursor ( ME_TextEditor editor,
int  nCursor 
)

Definition at line 580 of file caret.c.

581{
582 ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
583 WCHAR space = ' ';
584
585 /* FIXME no no no */
586 if (ME_IsSelection(editor))
587 ME_DeleteSelection(editor);
588
589 ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
591 ME_ReleaseStyle(pStyle);
592}
BOOL ME_IsSelection(ME_TextEditor *editor)
Definition: caret.c:1578
void ME_DeleteSelection(ME_TextEditor *editor)
Definition: caret.c:1584
static ME_DisplayItem * ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style, int flags)
Definition: caret.c:520
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN
Definition: style.c:462
#define MERF_ENDROW
Definition: editstr.h:124
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by handle_enter(), and SpecialChar().

◆ ME_InsertOLEFromCursor()

void ME_InsertOLEFromCursor ( ME_TextEditor editor,
const REOBJECT reo,
int  nCursor 
)

Definition at line 546 of file caret.c.

547{
548 ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
549 ME_DisplayItem *di;
550 WCHAR space = ' ';
551 ME_DisplayItem *di_prev = NULL;
552 struct re_object *reobj_prev = NULL;
553
554 /* FIXME no no no */
555 if (ME_IsSelection(editor))
556 ME_DeleteSelection(editor);
557
558 di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
560 di->member.run.reobj = create_re_object(reo);
561
562 di_prev = di;
563 while (ME_PrevRun(NULL, &di_prev, TRUE))
564 {
565 if (di_prev->member.run.reobj)
566 {
567 reobj_prev = di_prev->member.run.reobj;
568 break;
569 }
570 }
571 if (reobj_prev)
572 list_add_after(&reobj_prev->entry, &di->member.run.reobj->entry);
573 else
574 list_add_head(&editor->reobj_list, &di->member.run.reobj->entry);
575
576 ME_ReleaseStyle(pStyle);
577}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static struct re_object * create_re_object(const REOBJECT *reo)
Definition: caret.c:533
BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN
Definition: list.c:93
#define MERF_GRAPHICS
Definition: editstr.h:105
__WINE_SERVER_LIST_INLINE void list_add_after(struct list *elem, struct list *to_add)
Definition: list.h:78
struct list entry
Definition: editstr.h:154
struct re_object * reobj
Definition: editstr.h:168
struct list reobj_list
Definition: editstr.h:448

Referenced by insert_static_object(), and IRichEditOle_fnInsertObject().

◆ ME_InsertTextFromCursor()

void ME_InsertTextFromCursor ( ME_TextEditor editor,
int  nCursor,
const WCHAR str,
int  len,
ME_Style style 
)

Definition at line 595 of file caret.c.

597{
598 const WCHAR *pos;
599 ME_Cursor *p = NULL;
600 int oldLen;
601
602 /* FIXME really HERE ? */
603 if (ME_IsSelection(editor))
604 ME_DeleteSelection(editor);
605
606 /* FIXME: is this too slow? */
607 /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */
608 oldLen = ME_GetTextLength(editor);
609
610 /* text operations set modified state */
611 editor->nModifyStep = 1;
612
613 assert(style);
614
615 assert(nCursor>=0 && nCursor<editor->nCursors);
616 if (len == -1)
617 len = lstrlenW(str);
618
619 /* grow the text limit to fit our text */
620 if(editor->nTextLimit < oldLen +len)
621 editor->nTextLimit = oldLen + len;
622
623 pos = str;
624
625 while (len)
626 {
627 /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
628 while(pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t')
629 pos++;
630
631 if (pos != str) { /* handle text */
632 ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
633 } else if (*pos == '\t') { /* handle tabs */
634 WCHAR tab = '\t';
635 ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB);
636 pos++;
637 } else { /* handle EOLs */
638 ME_DisplayItem *tp, *end_run, *run, *prev;
639 int eol_len = 0;
640
641 /* Check if new line is allowed for this control */
642 if (!(editor->styleFlags & ES_MULTILINE))
643 break;
644
645 /* Find number of CR and LF in end of paragraph run */
646 if (*pos =='\r')
647 {
648 if (len > 1 && pos[1] == '\n')
649 eol_len = 2;
650 else if (len > 2 && pos[1] == '\r' && pos[2] == '\n')
651 eol_len = 3;
652 else
653 eol_len = 1;
654 } else {
655 assert(*pos == '\n');
656 eol_len = 1;
657 }
658 pos += eol_len;
659
660 if (!editor->bEmulateVersion10 && eol_len == 3)
661 {
662 /* handle special \r\r\n sequence (richedit 2.x and higher only) */
663 WCHAR space = ' ';
664 ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0);
665 } else {
666 const WCHAR cr = '\r', *eol_str = str;
667
668 if (!editor->bEmulateVersion10)
669 {
670 eol_str = &cr;
671 eol_len = 1;
672 }
673
674 p = &editor->pCursors[nCursor];
675
676 if (p->nOffset == p->pRun->member.run.len)
677 {
678 run = ME_FindItemFwd( p->pRun, diRun );
679 if (!run) run = p->pRun;
680 }
681 else
682 {
683 if (p->nOffset) ME_SplitRunSimple(editor, p);
684 run = p->pRun;
685 }
686
687 tp = ME_SplitParagraph(editor, run, style, eol_str, eol_len, 0);
688
689 end_run = ME_FindItemBack(tp, diRun);
690
691 /* Move any cursors that were at the end of the previous run to the beginning of the new para */
692 prev = ME_FindItemBack( end_run, diRun );
693 if (prev)
694 {
695 int i;
696 for (i = 0; i < editor->nCursors; i++)
697 {
698 if (editor->pCursors[i].pRun == prev &&
699 editor->pCursors[i].nOffset == prev->member.run.len)
700 {
701 editor->pCursors[i].pPara = tp;
702 editor->pCursors[i].pRun = run;
703 editor->pCursors[i].nOffset = 0;
704 }
705 }
706 }
707
708 }
709 }
710 len -= pos - str;
711 str = pos;
712 }
713}
Arabic default style
Definition: afstyles.h:94
#define lstrlenW
Definition: compat.h:750
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
ME_DisplayItem * ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:258
ME_DisplayItem * ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, const WCHAR *eol_str, int eol_len, int paraFlags) DECLSPEC_HIDDEN
Definition: para.c:545
#define MERF_TAB
Definition: editstr.h:107
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const WCHAR * str
int len
Definition: editstr.h:163

Referenced by fnTextSrv_TxSetText(), handle_enter(), ITextRange_fnSetText(), ME_AppendTableRow(), ME_Char(), ME_HandleMessage(), ME_ReplaceSel(), ME_RTFParAttrHook(), ME_RTFSpecialCharHook(), ME_SetText(), ME_StreamInText(), and RTFFlushUnicodeOutputBuffer().

◆ ME_InternalDeleteText()

BOOL ME_InternalDeleteText ( ME_TextEditor editor,
ME_Cursor start,
int  nChars,
BOOL  bForce 
)

Definition at line 360 of file caret.c.

362{
363 ME_Cursor c = *start;
364 int nOfs = ME_GetCursorOfs(start), text_len = ME_GetTextLength( editor );
365 int shift = 0;
366 int totalChars = nChars;
367 ME_DisplayItem *start_para;
368 BOOL delete_all = FALSE;
369
370 /* Prevent deletion past last end of paragraph run. */
371 nChars = min(nChars, text_len - nOfs);
372 if (nChars == text_len) delete_all = TRUE;
373 start_para = c.pPara;
374
375 if (!bForce)
376 {
377 ME_ProtectPartialTableDeletion(editor, &c, &nChars);
378 if (nChars == 0)
379 return FALSE;
380 }
381
382 while(nChars > 0)
383 {
384 ME_Run *run;
385 ME_CursorFromCharOfs(editor, nOfs+nChars, &c);
386 if (!c.nOffset &&
387 nOfs+nChars == (c.pRun->member.run.nCharOfs
388 + c.pPara->member.para.nCharOfs))
389 {
390 /* We aren't deleting anything in this run, so we will go back to the
391 * last run we are deleting text in. */
392 ME_PrevRun(&c.pPara, &c.pRun, TRUE);
393 c.nOffset = c.pRun->member.run.len;
394 }
395 run = &c.pRun->member.run;
396 if (run->nFlags & MERF_ENDPARA) {
397 int eollen = c.pRun->member.run.len;
398 BOOL keepFirstParaFormat;
399
400 if (!ME_FindItemFwd(c.pRun, diParagraph))
401 {
402 return TRUE;
403 }
404 keepFirstParaFormat = (totalChars == nChars && nChars <= eollen &&
405 run->nCharOfs);
406 if (!editor->bEmulateVersion10) /* v4.1 */
407 {
409 ME_DisplayItem *this_para = next_para->member.para.prev_para;
410
411 /* The end of paragraph before a table row is only deleted if there
412 * is nothing else on the line before it. */
413 if (this_para == start_para &&
414 next_para->member.para.nFlags & MEPF_ROWSTART)
415 {
416 /* If the paragraph will be empty, then it should be deleted, however
417 * it still might have text right now which would inherit the
418 * MEPF_STARTROW property if we joined it right now.
419 * Instead we will delete it after the preceding text is deleted. */
420 if (nOfs > this_para->member.para.nCharOfs) {
421 /* Skip this end of line. */
422 nChars -= (eollen < nChars) ? eollen : nChars;
423 continue;
424 }
425 keepFirstParaFormat = TRUE;
426 }
427 }
428 ME_JoinParagraphs(editor, c.pPara, keepFirstParaFormat);
429 /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
430 ME_CheckCharOffsets(editor);
431 nChars -= (eollen < nChars) ? eollen : nChars;
432 continue;
433 }
434 else
435 {
437 int nCharsToDelete = min(nChars, c.nOffset);
438 int i;
439
440 c.nOffset -= nCharsToDelete;
441
443
444 cursor = c;
445 /* nChars is the number of characters that should be deleted from the
446 PRECEDING runs (these BEFORE cursor.pRun)
447 nCharsToDelete is a number of chars to delete from THIS run */
448 nChars -= nCharsToDelete;
449 shift -= nCharsToDelete;
450 TRACE("Deleting %d (remaining %d) chars at %d in %s (%d)\n",
451 nCharsToDelete, nChars, c.nOffset,
452 debugstr_run( run ), run->len);
453
454 /* nOfs is a character offset (from the start of the document
455 to the current (deleted) run */
456 add_undo_insert_run( editor, nOfs + nChars, get_text( run, c.nOffset ), nCharsToDelete, run->nFlags, run->style );
457
458 ME_StrDeleteV(run->para->text, run->nCharOfs + c.nOffset, nCharsToDelete);
459 run->len -= nCharsToDelete;
460 TRACE("Post deletion string: %s (%d)\n", debugstr_run( run ), run->len);
461 TRACE("Shift value: %d\n", shift);
462
463 /* update cursors (including c) */
464 for (i=-1; i<editor->nCursors; i++) {
465 ME_Cursor *pThisCur = editor->pCursors + i;
466 if (i == -1) pThisCur = &c;
467 if (pThisCur->pRun == cursor.pRun) {
468 if (pThisCur->nOffset > cursor.nOffset) {
469 if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete)
470 pThisCur->nOffset = cursor.nOffset;
471 else
472 pThisCur->nOffset -= nCharsToDelete;
473 assert(pThisCur->nOffset >= 0);
474 assert(pThisCur->nOffset <= run->len);
475 }
476 if (pThisCur->nOffset == run->len)
477 {
478 pThisCur->pRun = ME_FindItemFwd(pThisCur->pRun, diRunOrParagraphOrEnd);
479 assert(pThisCur->pRun->type == diRun);
480 pThisCur->nOffset = 0;
481 }
482 }
483 }
484
485 /* c = updated data now */
486
487 if (c.pRun == cursor.pRun)
489 else
491
492 if (!cursor.pRun->member.run.len)
493 {
494 TRACE("Removing empty run\n");
495 ME_Remove(cursor.pRun);
497 }
498
499 shift = 0;
500 /*
501 ME_CheckCharOffsets(editor);
502 */
503 continue;
504 }
505 }
506 if (delete_all) ME_SetDefaultParaFormat( editor, &start_para->member.para.fmt );
507 return TRUE;
508}
BOOL add_undo_insert_run(ME_TextEditor *, int pos, const WCHAR *str, int len, int flags, ME_Style *style) DECLSPEC_HIDDEN
Definition: undo.c:131
void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: para.c:26
void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor) DECLSPEC_HIDDEN
Definition: run.c:171
void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN
Definition: list.c:160
void ME_PropagateCharOffset(ME_DisplayItem *p, int shift) DECLSPEC_HIDDEN
Definition: run.c:59
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars) DECLSPEC_HIDDEN
Definition: table.c:287
void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN
Definition: para.c:992
ME_DisplayItem * ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, BOOL keepFirstParaFormat) DECLSPEC_HIDDEN
Definition: para.c:687
void ME_Remove(ME_DisplayItem *diWhere) DECLSPEC_HIDDEN
Definition: list.c:35
void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift) DECLSPEC_HIDDEN
Definition: run.c:46
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars) DECLSPEC_HIDDEN
Definition: string.c:147
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
static const char * debugstr_run(const ME_Run *run)
Definition: editor.h:46
@ diRunOrParagraphOrEnd
Definition: editstr.h:97
GLuint start
Definition: gl.h:1545
#define shift
Definition: input.c:1755
#define min(a, b)
Definition: monoChain.cc:55
#define TRACE(s)
Definition: solgame.cpp:4
int nCharOfs
Definition: editstr.h:162
struct tagME_Paragraph * para
Definition: editstr.h:161
ME_Style * style
Definition: editstr.h:160

Referenced by copy_or_cut(), fnTextSrv_TxSetText(), ITextRange_fnSetText(), ME_DeleteTextAtCursor(), ME_HandleMessage(), ME_PlayUndoItem(), ME_ReplaceSel(), ME_RTFSpecialCharHook(), and ME_StreamIn().

◆ ME_InternalInsertTextFromCursor()

static ME_DisplayItem * ME_InternalInsertTextFromCursor ( ME_TextEditor editor,
int  nCursor,
const WCHAR str,
int  len,
ME_Style style,
int  flags 
)
static

Definition at line 520 of file caret.c.

523{
524 ME_Cursor *p = &editor->pCursors[nCursor];
525
526 editor->bCaretAtEnd = FALSE;
527
528 assert(p->pRun->type == diRun);
529
530 return ME_InsertRunAtCursor(editor, p, style, str, len, flags);
531}
ME_DisplayItem * ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, const WCHAR *str, int len, int flags) DECLSPEC_HIDDEN
Definition: run.c:325
GLbitfield flags
Definition: glext.h:7161

Referenced by ME_InsertEndRowFromCursor(), ME_InsertOLEFromCursor(), and ME_InsertTextFromCursor().

◆ ME_IsSelection()

◆ ME_LButtonDown()

void ME_LButtonDown ( ME_TextEditor editor,
int  x,
int  y,
int  clickNum 
)

Definition at line 1204 of file caret.c.

1205{
1206 ME_Cursor tmp_cursor;
1207 BOOL is_selection = FALSE, is_shift;
1208
1209 editor->nUDArrowX = -1;
1210
1211 x += editor->horz_si.nPos;
1212 y += editor->vert_si.nPos;
1213
1214 tmp_cursor = editor->pCursors[0];
1215 is_selection = ME_IsSelection(editor);
1216 is_shift = GetKeyState(VK_SHIFT) < 0;
1217
1218 ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd, FALSE);
1219
1220 if (x >= editor->rcFormat.left || is_shift)
1221 {
1222 if (clickNum > 1)
1223 {
1224 editor->pCursors[1] = editor->pCursors[0];
1225 if (is_shift) {
1226 if (x >= editor->rcFormat.left)
1227 ME_SelectByType(editor, stWord);
1228 else
1230 } else if (clickNum % 2 == 0) {
1231 ME_SelectByType(editor, stWord);
1232 } else {
1234 }
1235 }
1236 else if (!is_shift)
1237 {
1238 editor->nSelectionType = stPosition;
1239 editor->pCursors[1] = editor->pCursors[0];
1240 }
1241 else if (!is_selection)
1242 {
1243 editor->nSelectionType = stPosition;
1244 editor->pCursors[1] = tmp_cursor;
1245 }
1246 else if (editor->nSelectionType != stPosition)
1247 {
1249 }
1250 }
1251 else
1252 {
1253 if (clickNum < 2) {
1254 ME_SelectByType(editor, stLine);
1255 } else if (clickNum % 2 == 0 || is_shift) {
1257 } else {
1258 ME_SelectByType(editor, stDocument);
1259 }
1260 }
1261 ME_InvalidateSelection(editor);
1262 update_caret(editor);
1263 ME_SendSelChange(editor);
1264}
static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
Definition: caret.c:1152
static void ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
Definition: caret.c:899
@ stParagraph
Definition: editstr.h:360
#define VK_SHIFT
Definition: winuser.h:2202
SHORT WINAPI GetKeyState(_In_ int)

Referenced by ME_HandleMessage().

◆ ME_MouseMove()

void ME_MouseMove ( ME_TextEditor editor,
int  x,
int  y 
)

Definition at line 1266 of file caret.c.

1267{
1268 ME_Cursor tmp_cursor;
1269
1270 if (editor->nSelectionType == stDocument)
1271 return;
1272 x += editor->horz_si.nPos;
1273 y += editor->vert_si.nPos;
1274
1275 tmp_cursor = editor->pCursors[0];
1276 /* FIXME: do something with the return value of ME_FindPixelPos */
1277 ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd, TRUE);
1278
1279 ME_InvalidateSelection(editor);
1280 editor->pCursors[0] = tmp_cursor;
1282
1283 if (editor->nSelectionType != stPosition &&
1284 memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor)))
1285 {
1286 /* The scroll the cursor towards the other end, since it was the one
1287 * extended by ME_ExtendAnchorSelection */
1288 ME_EnsureVisible(editor, &editor->pCursors[1]);
1289 } else {
1290 ME_EnsureVisible(editor, &editor->pCursors[0]);
1291 }
1292
1293 ME_InvalidateSelection(editor);
1294 update_caret(editor);
1295 ME_SendSelChange(editor);
1296}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112

Referenced by ME_HandleMessage().

◆ ME_MoveCursorChars()

int ME_MoveCursorChars ( ME_TextEditor editor,
ME_Cursor cursor,
int  nRelOfs,
BOOL  final_eop 
)

Definition at line 720 of file caret.c.

721{
722 cursor->nOffset += nRelOfs;
723 if (cursor->nOffset < 0)
724 {
725 cursor->nOffset += cursor->pRun->member.run.nCharOfs;
726 if (cursor->nOffset >= 0)
727 {
728 /* new offset in the same paragraph */
729 do {
730 cursor->pRun = ME_FindItemBack(cursor->pRun, diRun);
731 } while (cursor->nOffset < cursor->pRun->member.run.nCharOfs);
732 cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
733 return nRelOfs;
734 }
735
736 cursor->nOffset += cursor->pPara->member.para.nCharOfs;
737 if (cursor->nOffset <= 0)
738 {
739 /* moved to the start of the text */
740 nRelOfs -= cursor->nOffset;
742 return nRelOfs;
743 }
744
745 /* new offset in a previous paragraph */
746 do {
747 cursor->pPara = cursor->pPara->member.para.prev_para;
748 } while (cursor->nOffset < cursor->pPara->member.para.nCharOfs);
749 cursor->nOffset -= cursor->pPara->member.para.nCharOfs;
750
751 cursor->pRun = ME_FindItemBack(cursor->pPara->member.para.next_para, diRun);
752 while (cursor->nOffset < cursor->pRun->member.run.nCharOfs) {
753 cursor->pRun = ME_FindItemBack(cursor->pRun, diRun);
754 }
755 cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
756 } else if (cursor->nOffset >= cursor->pRun->member.run.len) {
757 ME_DisplayItem *next_para;
758 int new_offset;
759
760 new_offset = ME_GetCursorOfs(cursor);
761 next_para = cursor->pPara->member.para.next_para;
762 if (new_offset < next_para->member.para.nCharOfs)
763 {
764 /* new offset in the same paragraph */
765 do {
766 cursor->nOffset -= cursor->pRun->member.run.len;
767 cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun);
768 } while (cursor->nOffset >= cursor->pRun->member.run.len);
769 return nRelOfs;
770 }
771
772 if (new_offset >= ME_GetTextLength(editor) + (final_eop ? 1 : 0))
773 {
774 /* new offset at the end of the text */
775 ME_SetCursorToEnd(editor, cursor, final_eop);
776 nRelOfs -= new_offset - (ME_GetTextLength(editor) + (final_eop ? 1 : 0));
777 return nRelOfs;
778 }
779
780 /* new offset in a following paragraph */
781 do {
782 cursor->pPara = next_para;
783 next_para = next_para->member.para.next_para;
784 } while (new_offset >= next_para->member.para.nCharOfs);
785
786 cursor->nOffset = new_offset - cursor->pPara->member.para.nCharOfs;
787 cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun);
788 while (cursor->nOffset >= cursor->pRun->member.run.len)
789 {
790 cursor->nOffset -= cursor->pRun->member.run.len;
791 cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun);
792 }
793 } /* else new offset is in the same run */
794 return nRelOfs;
795}

Referenced by get_textfont_prop_for_pos(), ME_ArrowKey(), ME_FindText(), ME_PlayUndoItem(), ME_ProtectPartialTableDeletion(), ME_StreamIn(), ME_StreamOutRTF(), and set_selection_cursors().

◆ ME_MoveCursorLines()

static void ME_MoveCursorLines ( ME_TextEditor editor,
ME_Cursor pCursor,
int  nRelOfs,
BOOL  extend 
)
static

Definition at line 1323 of file caret.c.

1324{
1325 ME_DisplayItem *pRun = pCursor->pRun;
1326 ME_DisplayItem *pOldPara = pCursor->pPara;
1327 ME_DisplayItem *pItem, *pNewPara;
1328 int x = ME_GetXForArrow(editor, pCursor);
1329
1330 if (editor->bCaretAtEnd && !pCursor->nOffset)
1331 if (!ME_PrevRun(&pOldPara, &pRun, TRUE))
1332 return;
1333
1334 if (nRelOfs == -1)
1335 {
1336 /* start of this row */
1337 pItem = ME_FindItemBack(pRun, diStartRow);
1338 assert(pItem);
1339 /* start of the previous row */
1340 pItem = ME_FindItemBack(pItem, diStartRow);
1341 if (!pItem) /* row not found */
1342 {
1343 if (extend)
1344 ME_SetCursorToStart(editor, pCursor);
1345 return;
1346 }
1347 pNewPara = ME_GetParagraph(pItem);
1348 if (pOldPara->member.para.nFlags & MEPF_ROWEND ||
1349 (pOldPara->member.para.pCell &&
1350 pOldPara->member.para.pCell != pNewPara->member.para.pCell))
1351 {
1352 /* Brought out of a cell */
1353 pNewPara = ME_GetTableRowStart(pOldPara)->member.para.prev_para;
1354 if (pNewPara->type == diTextStart)
1355 return; /* At the top, so don't go anywhere. */
1356 pItem = ME_FindItemFwd(pNewPara, diStartRow);
1357 }
1358 if (pNewPara->member.para.nFlags & MEPF_ROWEND)
1359 {
1360 /* Brought into a table row */
1361 ME_Cell *cell = &ME_FindItemBack(pNewPara, diCell)->member.cell;
1362 while (x < cell->pt.x && cell->prev_cell)
1363 cell = &cell->prev_cell->member.cell;
1364 if (cell->next_cell) /* else - we are still at the end of the row */
1365 pItem = ME_FindItemBack(cell->next_cell, diStartRow);
1366 }
1367 }
1368 else
1369 {
1370 /* start of the next row */
1371 pItem = ME_FindItemFwd(pRun, diStartRow);
1372 if (!pItem) /* row not found */
1373 {
1374 if (extend)
1375 ME_SetCursorToEnd(editor, pCursor, TRUE);
1376 return;
1377 }
1378 pNewPara = ME_GetParagraph(pItem);
1379 if (pOldPara->member.para.nFlags & MEPF_ROWSTART ||
1380 (pOldPara->member.para.pCell &&
1381 pOldPara->member.para.pCell != pNewPara->member.para.pCell))
1382 {
1383 /* Brought out of a cell */
1384 pNewPara = ME_GetTableRowEnd(pOldPara)->member.para.next_para;
1385 if (pNewPara->type == diTextEnd)
1386 return; /* At the bottom, so don't go anywhere. */
1387 pItem = ME_FindItemFwd(pNewPara, diStartRow);
1388 }
1389 if (pNewPara->member.para.nFlags & MEPF_ROWSTART)
1390 {
1391 /* Brought into a table row */
1392 ME_DisplayItem *cell = ME_FindItemFwd(pNewPara, diCell);
1393 while (cell->member.cell.next_cell &&
1394 x >= cell->member.cell.next_cell->member.cell.pt.x)
1395 cell = cell->member.cell.next_cell;
1396 pItem = ME_FindItemFwd(cell, diStartRow);
1397 }
1398 }
1399 if (!pItem)
1400 {
1401 /* row not found - ignore */
1402 return;
1403 }
1404 ME_FindRunInRow(editor, pItem, x, pCursor, &editor->bCaretAtEnd);
1405 assert(pCursor->pRun);
1406 assert(pCursor->pRun->type == diRun);
1407}
ME_DisplayItem * ME_GetTableRowStart(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:154
@ diCell
Definition: editstr.h:86
@ diTextStart
Definition: editstr.h:84
struct tagME_DisplayItem * prev_cell
Definition: editstr.h:229

Referenced by ME_ArrowKey().

◆ ME_MoveCursorWords()

BOOL ME_MoveCursorWords ( ME_TextEditor editor,
ME_Cursor cursor,
int  nRelOfs 
)

Definition at line 799 of file caret.c.

800{
801 ME_DisplayItem *pRun = cursor->pRun, *pOtherRun;
802 ME_DisplayItem *pPara = cursor->pPara;
803 int nOffset = cursor->nOffset;
804
805 if (nRelOfs == -1)
806 {
807 /* Backward movement */
808 while (TRUE)
809 {
810 nOffset = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ),
811 pRun->member.run.len, nOffset, WB_MOVEWORDLEFT);
812 if (nOffset)
813 break;
814 pOtherRun = ME_FindItemBack(pRun, diRunOrParagraph);
815 if (pOtherRun->type == diRun)
816 {
817 if (ME_CallWordBreakProc(editor, get_text( &pOtherRun->member.run, 0 ),
818 pOtherRun->member.run.len,
819 pOtherRun->member.run.len - 1,
821 && !(pRun->member.run.nFlags & MERF_ENDPARA)
822 && !(cursor->pRun == pRun && cursor->nOffset == 0)
823 && !ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ),
824 pRun->member.run.len, 0,
826 break;
827 pRun = pOtherRun;
828 nOffset = pOtherRun->member.run.len;
829 }
830 else if (pOtherRun->type == diParagraph)
831 {
832 if (cursor->pRun == pRun && cursor->nOffset == 0)
833 {
834 pPara = pOtherRun;
835 /* Skip empty start of table row paragraph */
836 if (pPara->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART)
837 pPara = pPara->member.para.prev_para;
838 /* Paragraph breaks are treated as separate words */
839 if (pPara->member.para.prev_para->type == diTextStart)
840 return FALSE;
841
842 pRun = ME_FindItemBack(pPara, diRun);
843 pPara = pPara->member.para.prev_para;
844 }
845 break;
846 }
847 }
848 }
849 else
850 {
851 /* Forward movement */
852 BOOL last_delim = FALSE;
853
854 while (TRUE)
855 {
856 if (last_delim && !ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ),
857 pRun->member.run.len, nOffset, WB_ISDELIMITER))
858 break;
859 nOffset = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ),
860 pRun->member.run.len, nOffset, WB_MOVEWORDRIGHT);
861 if (nOffset < pRun->member.run.len)
862 break;
863 pOtherRun = ME_FindItemFwd(pRun, diRunOrParagraphOrEnd);
864 if (pOtherRun->type == diRun)
865 {
866 last_delim = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ),
867 pRun->member.run.len, nOffset - 1, WB_ISDELIMITER);
868 pRun = pOtherRun;
869 nOffset = 0;
870 }
871 else if (pOtherRun->type == diParagraph)
872 {
873 if (pOtherRun->member.para.nFlags & MEPF_ROWSTART)
874 pOtherRun = pOtherRun->member.para.next_para;
875 if (cursor->pRun == pRun) {
876 pPara = pOtherRun;
877 pRun = ME_FindItemFwd(pPara, diRun);
878 }
879 nOffset = 0;
880 break;
881 }
882 else /* diTextEnd */
883 {
884 if (cursor->pRun == pRun)
885 return FALSE;
886 nOffset = 0;
887 break;
888 }
889 }
890 }
891 cursor->pPara = pPara;
892 cursor->pRun = pRun;
893 cursor->nOffset = nOffset;
894 return TRUE;
895}
int ME_CallWordBreakProc(ME_TextEditor *editor, WCHAR *str, INT len, INT start, INT code) DECLSPEC_HIDDEN
Definition: string.c:204
#define WB_MOVEWORDRIGHT
Definition: richedit.h:1002
#define WB_MOVEWORDLEFT
Definition: richedit.h:1000
#define WB_ISDELIMITER
Definition: winuser.h:549

Referenced by handle_EM_SETCHARFORMAT(), ME_ArrowKey(), ME_ExtendAnchorSelection(), and ME_SelectByType().

◆ ME_SelectByType()

static void ME_SelectByType ( ME_TextEditor editor,
ME_SelectionType  selectionType 
)
static

Definition at line 899 of file caret.c.

900{
901 /* pCursor[0] is the end of the selection
902 * pCursor[1] is the start of the selection (or the position selection anchor)
903 * pCursor[2] and [3] are the selection anchors that are backed up
904 * so they are kept when the selection changes for drag selection.
905 */
906
907 editor->nSelectionType = selectionType;
908 switch(selectionType)
909 {
910 case stPosition:
911 break;
912 case stWord:
913 ME_MoveCursorWords(editor, &editor->pCursors[0], +1);
914 editor->pCursors[1] = editor->pCursors[0];
915 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
916 break;
917 case stLine:
918 case stParagraph:
919 {
920 ME_DisplayItem *pItem;
921 ME_DIType fwdSearchType, backSearchType;
922 if (selectionType == stParagraph) {
923 backSearchType = diParagraph;
924 fwdSearchType = diParagraphOrEnd;
925 } else {
926 backSearchType = diStartRow;
927 fwdSearchType = diStartRowOrParagraphOrEnd;
928 }
929 pItem = ME_FindItemFwd(editor->pCursors[0].pRun, fwdSearchType);
930 assert(pItem);
931 if (pItem->type == diTextEnd)
932 editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun);
933 else
934 editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun);
935 editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun);
936 editor->pCursors[0].nOffset = 0;
937
938 pItem = ME_FindItemBack(pItem, backSearchType);
939 editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun);
940 editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun);
941 editor->pCursors[1].nOffset = 0;
942 break;
943 }
944 case stDocument:
945 /* Select everything with cursor anchored from the start of the text */
946 editor->nSelectionType = stDocument;
947 ME_SetCursorToStart(editor, &editor->pCursors[1]);
948 ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE);
949 break;
950 default: assert(0);
951 }
952 /* Store the anchor positions for extending the selection. */
953 editor->pCursors[2] = editor->pCursors[0];
954 editor->pCursors[3] = editor->pCursors[1];
955}

Referenced by ME_LButtonDown().

◆ ME_SendSelChange()

void ME_SendSelChange ( ME_TextEditor editor)

Definition at line 1598 of file caret.c.

1599{
1600 SELCHANGE sc;
1601
1602 sc.nmhdr.hwndFrom = NULL;
1603 sc.nmhdr.idFrom = 0;
1604 sc.nmhdr.code = EN_SELCHANGE;
1605 ME_GetSelectionOfs(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
1606 sc.seltyp = SEL_EMPTY;
1607 if (sc.chrg.cpMin != sc.chrg.cpMax)
1608 sc.seltyp |= SEL_TEXT;
1609 if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */
1610 sc.seltyp |= SEL_MULTICHAR;
1611
1612 if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax)
1613 {
1614 ME_ClearTempStyle(editor);
1615
1616 editor->notified_cr = sc.chrg;
1617
1618 if (editor->nEventMask & ENM_SELCHANGE)
1619 {
1620 TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n",
1621 sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,
1622 (sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "",
1623 (sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : "");
1624 ITextHost_TxNotify(editor->texthost, sc.nmhdr.code, &sc);
1625 }
1626 }
1627}
#define ITextHost_TxNotify(This, a, b)
Definition: editor.h:322
void ME_ClearTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: style.c:523
#define SEL_EMPTY
Definition: richedit.h:822
#define SEL_MULTICHAR
Definition: richedit.h:825
#define EN_SELCHANGE
Definition: richedit.h:193
#define SEL_TEXT
Definition: richedit.h:823
#define ENM_SELCHANGE
Definition: richedit.h:478
LONG cpMax
Definition: richedit.h:501
LONG cpMin
Definition: richedit.h:500
NMHDR nmhdr
Definition: richedit.h:685
WORD seltyp
Definition: richedit.h:687
CHARRANGE chrg
Definition: richedit.h:686
CHARRANGE notified_cr
Definition: editstr.h:438
UINT_PTR idFrom
Definition: winuser.h:3158
UINT code
Definition: winuser.h:3159
HWND hwndFrom
Definition: winuser.h:3157

Referenced by ME_ArrowKey(), ME_LButtonDown(), ME_MouseMove(), ME_StreamIn(), ME_TabPressedInTable(), ME_UpdateRepaint(), and set_selection().

◆ ME_SetCursorToEnd()

static void ME_SetCursorToEnd ( ME_TextEditor editor,
ME_Cursor cursor,
BOOL  final_eop 
)
static

Definition at line 34 of file caret.c.

35{
36 cursor->pPara = editor->pBuffer->pLast->member.para.prev_para;
37 cursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
38 cursor->nOffset = final_eop ? cursor->pRun->member.run.len : 0;
39}

Referenced by ME_ArrowCtrlEnd(), ME_ArrowPageDown(), ME_FindPixelPos(), ME_GetTextLength(), ME_MoveCursorChars(), ME_MoveCursorLines(), ME_SelectByType(), and set_selection_cursors().

◆ ME_SetCursorToStart()

◆ set_selection_cursors()

int set_selection_cursors ( ME_TextEditor editor,
int  from,
int  to 
)

Definition at line 132 of file caret.c.

133{
134 int selectionEnd = 0;
135 const int len = ME_GetTextLength(editor);
136
137 /* all negative values are effectively the same */
138 if (from < 0)
139 from = -1;
140 if (to < 0)
141 to = -1;
142
143 /* select all */
144 if (from == 0 && to == -1)
145 {
146 ME_SetCursorToStart(editor, &editor->pCursors[1]);
147 ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE);
148 return len + 1;
149 }
150
151 /* if both values are equal and also out of bound, that means to */
152 /* put the selection at the end of the text */
153 if ((from == to) && (to < 0 || to > len))
154 {
155 selectionEnd = 1;
156 }
157 else
158 {
159 /* if from is negative and to is positive then selection is */
160 /* deselected and caret moved to end of the current selection */
161 if (from < 0)
162 {
163 int start, end;
164 ME_GetSelectionOfs(editor, &start, &end);
165 if (start != end)
166 {
167 if (end > len)
168 {
169 editor->pCursors[0].nOffset = 0;
170 end --;
171 }
172 editor->pCursors[1] = editor->pCursors[0];
173 }
174 return end;
175 }
176
177 /* adjust to if it's a negative value */
178 if (to < 0)
179 to = len + 1;
180
181 /* flip from and to if they are reversed */
182 if (from>to)
183 {
184 int tmp = from;
185 from = to;
186 to = tmp;
187 }
188
189 /* after fiddling with the values, we find from > len && to > len */
190 if (from > len)
191 selectionEnd = 1;
192 /* special case with to too big */
193 else if (to > len)
194 to = len + 1;
195 }
196
197 if (selectionEnd)
198 {
199 ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE);
200 editor->pCursors[1] = editor->pCursors[0];
201 return len;
202 }
203
204 ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]);
205 editor->pCursors[0] = editor->pCursors[1];
206 ME_MoveCursorChars(editor, &editor->pCursors[0], to - from, FALSE);
207 /* Selection is not allowed in the middle of an end paragraph run. */
208 if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA)
209 editor->pCursors[1].nOffset = 0;
210 if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA)
211 {
212 if (to > len)
213 editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len;
214 else
215 editor->pCursors[0].nOffset = 0;
216 }
217 return to;
218}
GLuint GLuint end
Definition: gl.h:1545

Referenced by fnTextSrv_TxSetText(), ME_HandleMessage(), ME_StreamIn(), and set_selection().

◆ show_caret()

void show_caret ( ME_TextEditor editor)

Definition at line 282 of file caret.c.

283{
285 editor->caret_hidden = FALSE;
286}

Referenced by update_caret().

◆ update_caret()

void update_caret ( ME_TextEditor editor)

Definition at line 298 of file caret.c.

299{
300 int x, y, height;
301
302 if (!editor->bHaveFocus) return;
303 if (!ME_IsSelection(editor))
304 {
305 ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height);
306 if (height != editor->caret_height) create_caret(editor);
307 x = min(x, editor->rcFormat.right-1);
309 show_caret(editor);
310 }
311 else
312 hide_caret(editor);
313#ifdef __REACTOS__
315 {
316 HIMC hIMC = ImmGetContext(editor->hWnd);
317 if (hIMC)
318 {
320 LOGFONTW lf;
321 COMPOSITIONFORM CompForm;
322 POINT pt = { x, y };
323
324 CompForm.ptCurrentPos = pt;
325 if (editor->styleFlags & ES_MULTILINE)
326 {
327 CompForm.dwStyle = CFS_RECT;
328 CompForm.rcArea = editor->rcFormat;
329 }
330 else
331 {
332 CompForm.dwStyle = CFS_POINT;
333 SetRectEmpty(&CompForm.rcArea);
334 }
335 ImmSetCompositionWindow(hIMC, &CompForm);
336
337 fmt.cbSize = sizeof(fmt);
339
340 ZeroMemory(&lf, sizeof(lf));
342 if (fmt.dwMask & CFM_SIZE)
343 {
345 lf.lfHeight = -MulDiv(fmt.yHeight, GetDeviceCaps(hdc, LOGPIXELSY), 1440);
346 DeleteDC(hdc);
347 }
348 if (fmt.dwMask & CFM_CHARSET)
349 lf.lfCharSet = fmt.bCharSet;
350 if (fmt.dwMask & CFM_FACE)
351 lstrcpynW(lf.lfFaceName, fmt.szFaceName, ARRAY_SIZE(lf.lfFaceName));
352 ImmSetCompositionFontW(hIMC, &lf);
353
354 ImmReleaseContext(editor->hWnd, hIMC);
355 }
356 }
357#endif
358}
#define ARRAY_SIZE(A)
Definition: main.h:33
DWORD HIMC
Definition: dimm.idl:75
#define lstrcpynW
Definition: compat.h:738
BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
Definition: ime.c:1744
BOOL WINAPI ImmIsIME(HKL hKL)
Definition: ime.c:880
BOOL WINAPI ImmSetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1583
HIMC WINAPI ImmGetContext(HWND hWnd)
Definition: imm.c:1044
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1085
void create_caret(ME_TextEditor *editor)
Definition: caret.c:272
void show_caret(ME_TextEditor *editor)
Definition: caret.c:282
#define ITextHost_TxSetCaretPos(This, a, b)
Definition: editor.h:297
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN
Definition: run.c:801
#define CFS_RECT
Definition: imm.h:324
#define CFS_POINT
Definition: imm.h:325
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
#define CFM_CHARSET
Definition: richedit.h:358
#define CFM_SIZE
Definition: richedit.h:362
#define CFM_FACE
Definition: richedit.h:360
RECT rcArea
Definition: dimm.idl:88
DWORD dwStyle
Definition: dimm.idl:86
POINT ptCurrentPos
Definition: dimm.idl:87
LONG lfHeight
Definition: dimm.idl:59
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
BYTE lfCharSet
Definition: dimm.idl:67
Definition: dsound.c:943
#define ZeroMemory
Definition: winbase.h:1712
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define LOGPIXELSY
Definition: wingdi.h:719
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define DEFAULT_CHARSET
Definition: wingdi.h:384
BOOL WINAPI DeleteDC(_In_ HDC)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)

Referenced by ME_ArrowKey(), ME_HandleMessage(), ME_LButtonDown(), ME_MouseMove(), ME_StreamIn(), ME_TabPressedInTable(), ME_WmCreate(), RichEditWndProc_common(), and set_selection().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( richedit  )