ReactOS 0.4.16-dev-1481-ga753f34
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, LONG *from, LONG *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 cursor_coords (ME_TextEditor *editor, ME_Cursor *cursor, 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 struct re_objectcreate_re_object (const REOBJECT *reo, ME_Run *run)
 
HRESULT editor_insert_oleobj (ME_TextEditor *editor, const REOBJECT *reo)
 
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_Paragraphpixel_pos_in_table_row (int x, int y, ME_Paragraph *para)
 
static BOOL row_cursor (ME_TextEditor *editor, ME_Row *row, int x, ME_Cursor *cursor)
 
static BOOL cursor_from_virtual_coords (ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL final_eop)
 
BOOL cursor_from_coords (ME_TextEditor *editor, int x, int y, ME_Cursor *cursor)
 
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 cursor_move_line (ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend)
 
static void ME_ArrowPageUp (ME_TextEditor *editor, ME_Cursor *cursor)
 
static void ME_ArrowPageDown (ME_TextEditor *editor, ME_Cursor *cursor)
 
static void ME_ArrowHome (ME_TextEditor *editor, ME_Cursor *cursor)
 
static void ME_ArrowCtrlHome (ME_TextEditor *editor, ME_Cursor *pCursor)
 
static void ME_ArrowEnd (ME_TextEditor *editor, ME_Cursor *cursor)
 
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 251 of file caret.c.

252{
253 int x, y, height;
254
255 cursor_coords( editor, &editor->pCursors[0], &x, &y, &height );
257 editor->caret_height = height;
258 editor->caret_hidden = TRUE;
259}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
void cursor_coords(ME_TextEditor *editor, ME_Cursor *cursor, int *x, int *y, int *height)
Definition: caret.c:221
#define ITextHost_TxCreateCaret(This, a, b, c)
Definition: editor.h:340
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
ITextHost2 * texthost
Definition: editstr.h:391
ME_Cursor * pCursors
Definition: editstr.h:396
BOOL caret_hidden
Definition: editstr.h:454

Referenced by editor_handle_message(), and update_caret().

◆ create_re_object()

static struct re_object * create_re_object ( const REOBJECT reo,
ME_Run run 
)
static

Definition at line 490 of file caret.c.

491{
492 struct re_object *reobj = malloc(sizeof(*reobj));
493
494 if (!reobj)
495 {
496 WARN("Fail to allocate re_object.\n");
497 return NULL;
498 }
499 ME_CopyReObject(&reobj->obj, reo, REO_GETOBJ_ALL_INTERFACES);
500 reobj->run = run;
501 return reobj;
502}
#define WARN(fmt,...)
Definition: precomp.h:61
#define malloc
Definition: debug_ros.c:4
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
Definition: richole.c:5919
struct tagME_Run * run
Definition: editstr.h:155
REOBJECT obj
Definition: editstr.h:154

Referenced by editor_insert_oleobj().

◆ cursor_coords()

void cursor_coords ( ME_TextEditor editor,
ME_Cursor cursor,
int x,
int y,
int height 
)

Definition at line 221 of file caret.c.

223{
224 ME_Row *row;
225 ME_Run *run = cursor->run;
226 ME_Paragraph *para = cursor->para;
227 ME_Run *size_run = run, *prev;
229 int run_x;
230 HDC hdc = ITextHost_TxGetDC( editor->texthost );
231
232 assert(~para->nFlags & MEPF_REWRAP);
233
235
236 ME_InitContext( &c, editor, hdc );
237
238 if (!cursor->nOffset && (prev = run_prev( run ))) size_run = prev;
239
240 run_x = ME_PointFromCharContext( &c, run, cursor->nOffset, TRUE );
241
242 *height = size_run->nAscent + size_run->nDescent;
243 *x = c.rcView.left + run->pt.x + run_x - editor->horz_si.nPos;
244 *y = c.rcView.top + para->pt.y + row->nBaseline
245 + run->pt.y - size_run->nAscent - editor->vert_si.nPos;
248 return;
249}
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
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 assert(x)
Definition: debug.h:53
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order)
Definition: run.c:613
ME_Row * row_from_cursor(ME_Cursor *cursor)
Definition: row.c:74
ME_Run * run_prev(ME_Run *run)
Definition: run.c:82
#define ITextHost_TxGetDC(This)
Definition: editor.h:332
#define ITextHost_TxReleaseDC(This, a)
Definition: editor.h:333
#define MEPF_REWRAP
Definition: editstr.h:139
const GLubyte * c
Definition: glext.h:8905
const char cursor[]
Definition: icontest.c:13
#define c
Definition: ke_i.h:80
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
int nAscent
Definition: editstr.h:166
POINT pt
Definition: editstr.h:167
int nDescent
Definition: editstr.h:166
SCROLLINFO vert_si
Definition: editstr.h:449
SCROLLINFO horz_si
Definition: editstr.h:449
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48

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

◆ cursor_from_coords()

BOOL cursor_from_coords ( ME_TextEditor editor,
int  x,
int  y,
ME_Cursor cursor 
)

Definition at line 1070 of file caret.c.

1071{
1072 x += editor->horz_si.nPos;
1073 y += editor->vert_si.nPos;
1074 return cursor_from_virtual_coords( editor, x, y, cursor, FALSE );
1075}
#define FALSE
Definition: types.h:117
static BOOL cursor_from_virtual_coords(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL final_eop)
Definition: caret.c:1012

Referenced by editor_handle_message(), editor_set_cursor(), and link_notify().

◆ cursor_from_virtual_coords()

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

Definition at line 1012 of file caret.c.

1014{
1015 ME_Paragraph *para = editor_first_para( editor );
1016 ME_Row *row = NULL, *next_row;
1017 BOOL isExact = TRUE;
1018
1019 x -= editor->rcFormat.left;
1020 y -= editor->rcFormat.top;
1021
1022 /* find paragraph */
1023 for (; para_next( para ); para = para_next( para ))
1024 {
1025 if (y < para->pt.y + para->nHeight)
1026 {
1027 if (para->nFlags & MEPF_ROWSTART)
1028 para = pixel_pos_in_table_row( x, y, para );
1029 y -= para->pt.y;
1030 row = para_first_row( para );
1031 break;
1032 }
1033 else if (para->nFlags & MEPF_ROWSTART)
1034 {
1035 para = table_row_end( para );
1036 }
1037 }
1038 /* find row */
1039 while (row)
1040 {
1041 if (y < row->pt.y + row->nHeight) break;
1042 next_row = row_next( row );
1043 if (!next_row) break;
1044 row = next_row;
1045 }
1046
1047 if (!row && !final_eop && para_prev( para ))
1048 {
1049 /* The position is below the last paragraph, so the last row will be used
1050 * rather than the end of the text, so the x position will be used to
1051 * determine the offset closest to the pixel position. */
1052 isExact = FALSE;
1053 row = para_end_row( para_prev( para ) );
1054 }
1055
1056 if (row) return row_cursor( editor, row, x, result ) && isExact;
1057
1058 ME_SetCursorToEnd(editor, result, TRUE);
1059 return FALSE;
1060}
static BOOL row_cursor(ME_TextEditor *editor, ME_Row *row, int x, ME_Cursor *cursor)
Definition: caret.c:967
static ME_Paragraph * pixel_pos_in_table_row(int x, int y, ME_Paragraph *para)
Definition: caret.c:929
static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop)
Definition: caret.c:34
ME_Paragraph * editor_first_para(ME_TextEditor *editor)
Definition: editor.c:276
#define pt(x, y)
Definition: drawing.c:79
ME_Row * para_first_row(ME_Paragraph *para)
Definition: para.c:132
ME_Row * para_end_row(ME_Paragraph *para)
Definition: para.c:141
ME_Paragraph * table_row_end(ME_Paragraph *para)
Definition: table.c:127
ME_Paragraph * para_prev(ME_Paragraph *para)
Definition: para.c:63
ME_Row * row_next(ME_Row *row)
Definition: row.c:27
ME_Paragraph * para_next(ME_Paragraph *para)
Definition: para.c:57
#define MEPF_ROWSTART
Definition: editstr.h:142
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint64EXT * result
Definition: glext.h:11304
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306

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

◆ cursor_move_line()

static void cursor_move_line ( ME_TextEditor editor,
ME_Cursor cursor,
BOOL  up,
BOOL  extend 
)
static

Definition at line 1265 of file caret.c.

1266{
1267 ME_Paragraph *old_para = cursor->para, *new_para;
1269 int x = ME_GetXForArrow( editor, cursor );
1270
1271 if (up)
1272 {
1273 /* start of the previous row */
1275 if (!row)
1276 {
1277 if (extend) ME_SetCursorToStart( editor, cursor );
1278 return;
1279 }
1280 new_para = row_para( row );
1281 if (old_para->nFlags & MEPF_ROWEND ||
1282 (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para )))
1283 {
1284 /* Brought out of a cell */
1285 new_para = para_prev( table_row_start( old_para ));
1286 if (!new_para) return; /* At the top, so don't go anywhere. */
1287 row = para_first_row( new_para );
1288 }
1289 if (new_para->nFlags & MEPF_ROWEND)
1290 {
1291 /* Brought into a table row */
1292 ME_Cell *cell = table_row_end_cell( new_para );
1293 while (x < cell->pt.x && cell_prev( cell ))
1294 cell = cell_prev( cell );
1295 if (cell_next( cell )) /* else - we are still at the end of the row */
1296 row = para_end_row( cell_end_para( cell ) );
1297 }
1298 }
1299 else
1300 {
1301 /* start of the next row */
1303 if (!row)
1304 {
1305 if (extend) ME_SetCursorToEnd( editor, cursor, TRUE );
1306 return;
1307 }
1308 new_para = row_para( row );
1309 if (old_para->nFlags & MEPF_ROWSTART ||
1310 (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para )))
1311 {
1312 /* Brought out of a cell */
1313 new_para = para_next( table_row_end( old_para ) );
1314 if (!para_next( new_para )) return; /* At the bottom, so don't go anywhere. */
1315 row = para_first_row( new_para );
1316 }
1317 if (new_para->nFlags & MEPF_ROWSTART)
1318 {
1319 /* Brought into a table row */
1320 ME_Cell *cell = table_row_first_cell( new_para );
1321 while (cell_next( cell ) && x >= cell_next( cell )->pt.x)
1322 cell = cell_next( cell );
1323 row = para_first_row( cell_first_para( cell ) );
1324 }
1325 }
1326 if (!row) return;
1327
1328 row_cursor( editor, row, x, cursor );
1329}
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27
static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1248
ME_Cell * table_row_end_cell(ME_Paragraph *para)
Definition: table.c:178
ME_Paragraph * cell_first_para(ME_Cell *cell)
Definition: table.c:202
ME_Cell * cell_next(ME_Cell *cell)
Definition: table.c:192
ME_Cell * cell_prev(ME_Cell *cell)
Definition: table.c:197
ME_Paragraph * row_para(ME_Row *row)
Definition: row.c:103
ME_Cell * table_row_first_cell(ME_Paragraph *para)
Definition: table.c:170
ME_Cell * para_cell(ME_Paragraph *para)
Definition: para.c:127
ME_Row * row_prev_all_paras(ME_Row *row)
Definition: row.c:45
ME_Row * row_next_all_paras(ME_Row *row)
Definition: row.c:36
ME_Paragraph * table_row_start(ME_Paragraph *para)
Definition: table.c:142
ME_Paragraph * cell_end_para(ME_Cell *cell)
Definition: table.c:207
#define MEPF_ROWEND
Definition: editstr.h:143
#define up(mutex)
Definition: glue.h:30

Referenced by ME_ArrowKey().

◆ editor_insert_oleobj()

HRESULT editor_insert_oleobj ( ME_TextEditor editor,
const REOBJECT reo 
)

Definition at line 504 of file caret.c.

505{
506 ME_Run *run, *prev;
507 const WCHAR space = ' ';
508 struct re_object *reobj_prev = NULL;
509 ME_Cursor *cursor, cursor_from_ofs;
511 HRESULT hr;
513
514 if (editor->lpOleCallback)
515 {
516 hr = IRichEditOleCallback_QueryInsertObject(editor->lpOleCallback, (LPCLSID)&reo->clsid, reo->pstg, REO_CP_SELECTION);
517 if (hr != S_OK)
518 return hr;
519 }
520
521 extent = reo->sizel;
522 if (!extent.cx && !extent.cy && reo->poleobj)
523 {
524 hr = IOleObject_GetExtent( reo->poleobj, DVASPECT_CONTENT, &extent );
525 if (FAILED(hr))
526 {
527 extent.cx = 0;
528 extent.cy = 0;
529 }
530 }
531
532 if (reo->cp == REO_CP_SELECTION)
533 cursor = editor->pCursors;
534 else
535 {
536 cursor_from_char_ofs( editor, reo->cp, &cursor_from_ofs );
537 cursor = &cursor_from_ofs;
538 }
540
541 if (ME_IsSelection(editor))
542 ME_DeleteSelection(editor);
543
544 run = run_insert( editor, cursor, style, &space, 1, MERF_GRAPHICS );
545
546 run->reobj = create_re_object( reo, run );
547 run->reobj->obj.sizel = extent;
548
549 prev = run;
550 while ((prev = run_prev_all_paras( prev )))
551 {
552 if (prev->reobj)
553 {
554 reobj_prev = prev->reobj;
555 break;
556 }
557 }
558 if (reobj_prev)
559 list_add_after(&reobj_prev->entry, &run->reobj->entry);
560 else
561 list_add_head(&editor->reobj_list, &run->reobj->entry);
562
564 return S_OK;
565}
Arabic default style
Definition: afstyles.h:94
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
BOOL ME_IsSelection(ME_TextEditor *editor)
Definition: caret.c:1419
void ME_DeleteSelection(ME_TextEditor *editor)
Definition: caret.c:1425
static struct re_object * create_re_object(const REOBJECT *reo, ME_Run *run)
Definition: caret.c:490
ME_Style * style_get_insert_style(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: style.c:476
void ME_ReleaseStyle(ME_Style *item)
Definition: style.c:462
ME_Run * run_insert(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, const WCHAR *str, int len, int flags)
Definition: run.c:380
ME_Run * run_prev_all_paras(ME_Run *run)
Definition: run.c:110
void cursor_from_char_ofs(ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor)
Definition: run.c:245
#define MERF_GRAPHICS
Definition: editstr.h:103
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
__WINE_SERVER_LIST_INLINE void list_add_after(struct list *elem, struct list *to_add)
Definition: list.h:78
HRESULT hr
Definition: shlfolder.c:183
CLSID clsid
Definition: richole.idl:60
LPSTORAGE pstg
Definition: richole.idl:62
LPOLEOBJECT poleobj
Definition: richole.idl:61
LONG cp
Definition: richole.idl:59
SIZEL sizel
Definition: richole.idl:64
struct list entry
Definition: editstr.h:153
struct re_object * reobj
Definition: editstr.h:168
struct list reobj_list
Definition: editstr.h:459
LPRICHEDITOLECALLBACK lpOleCallback
Definition: editstr.h:427
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by insert_static_object(), and IRichEditOle_fnInsertObject().

◆ hide_caret()

void hide_caret ( ME_TextEditor editor)

Definition at line 267 of file caret.c.

268{
269 /* calls to HideCaret are cumulative; do so only once */
270 if (!editor->caret_hidden)
271 {
273 editor->caret_hidden = TRUE;
274 }
275}
#define ITextHost_TxShowCaret(This, a)
Definition: editor.h:341

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

◆ ME_ArrowCtrlEnd()

static void ME_ArrowCtrlEnd ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1414 of file caret.c.

1415{
1416 ME_SetCursorToEnd(editor, pCursor, FALSE);
1417}

Referenced by ME_ArrowKey().

◆ ME_ArrowCtrlHome()

static void ME_ArrowCtrlHome ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1402 of file caret.c.

1403{
1404 ME_SetCursorToStart(editor, pCursor);
1405}

Referenced by ME_ArrowKey().

◆ ME_ArrowEnd()

static void ME_ArrowEnd ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1407 of file caret.c.

1408{
1410
1412}
void row_end_cursor(ME_Row *row, ME_Cursor *cursor, BOOL include_eop)
Definition: row.c:92

Referenced by ME_ArrowKey().

◆ ME_ArrowHome()

static void ME_ArrowHome ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1395 of file caret.c.

1396{
1398
1400}
void row_first_cursor(ME_Row *row, ME_Cursor *cursor)
Definition: row.c:82

Referenced by ME_ArrowKey().

◆ ME_ArrowKey()

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

Definition at line 1471 of file caret.c.

1472{
1473 int nCursor = 0;
1474 ME_Cursor *p = &editor->pCursors[nCursor];
1475 ME_Cursor tmp_curs = *p;
1476 BOOL success = FALSE;
1477
1478 ME_CheckCharOffsets(editor);
1479 switch(nVKey) {
1480 case VK_LEFT:
1481 if (ctrl)
1482 success = ME_MoveCursorWords(editor, &tmp_curs, -1);
1483 else
1484 success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend);
1485 break;
1486 case VK_RIGHT:
1487 if (ctrl)
1488 success = ME_MoveCursorWords(editor, &tmp_curs, +1);
1489 else
1490 success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend);
1491 break;
1492 case VK_UP:
1493 cursor_move_line( editor, &tmp_curs, TRUE, extend );
1494 break;
1495 case VK_DOWN:
1496 cursor_move_line( editor, &tmp_curs, FALSE, extend );
1497 break;
1498 case VK_PRIOR:
1499 ME_ArrowPageUp(editor, &tmp_curs);
1500 break;
1501 case VK_NEXT:
1502 ME_ArrowPageDown(editor, &tmp_curs);
1503 break;
1504 case VK_HOME: {
1505 if (ctrl)
1506 ME_ArrowCtrlHome(editor, &tmp_curs);
1507 else
1508 ME_ArrowHome(editor, &tmp_curs);
1509 break;
1510 }
1511 case VK_END:
1512 if (ctrl)
1513 ME_ArrowCtrlEnd(editor, &tmp_curs);
1514 else
1515 ME_ArrowEnd(editor, &tmp_curs);
1516 break;
1517 }
1518
1519 if (!extend)
1520 editor->pCursors[1] = tmp_curs;
1521 *p = tmp_curs;
1522
1523 ME_InvalidateSelection(editor);
1524 ME_Repaint(editor);
1525 hide_caret(editor);
1526 editor_ensure_visible( editor, &tmp_curs );
1527 update_caret(editor);
1528 ME_SendSelChange(editor);
1529 return success;
1530}
static void cursor_move_line(ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend)
Definition: caret.c:1265
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1395
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:709
BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
Definition: caret.c:789
void hide_caret(ME_TextEditor *editor)
Definition: caret.c:267
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1414
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1439
static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1331
static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1364
void update_caret(ME_TextEditor *editor)
Definition: caret.c:277
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1402
static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1407
void ME_InvalidateSelection(ME_TextEditor *editor)
Definition: paint.c:1253
void ME_Repaint(ME_TextEditor *editor)
Definition: paint.c:121
void ME_CheckCharOffsets(ME_TextEditor *editor)
Definition: run.c:178
void editor_ensure_visible(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: paint.c:1210
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:2261
#define VK_NEXT
Definition: winuser.h:2257
#define VK_END
Definition: winuser.h:2258
#define VK_HOME
Definition: winuser.h:2259
#define VK_LEFT
Definition: winuser.h:2260
#define VK_RIGHT
Definition: winuser.h:2262
#define VK_DOWN
Definition: winuser.h:2263
#define VK_PRIOR
Definition: winuser.h:2256

Referenced by ME_KeyDown().

◆ ME_ArrowPageDown()

static void ME_ArrowPageDown ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1364 of file caret.c.

1365{
1366 ME_Row *row = para_end_row( para_prev( editor_end_para( editor ) ) ), *last_row;
1367 int x, yd, old_scroll_pos = editor->vert_si.nPos;
1368
1369 x = ME_GetXForArrow( editor, cursor );
1370
1371 if (editor->vert_si.nPos >= row_para( row )->pt.y + row->pt.y - editor->sizeWindow.cy)
1372 ME_SetCursorToEnd( editor, cursor, FALSE );
1373 else
1374 {
1376
1377 /* For native richedit controls:
1378 * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us
1379 * v4.1 can scroll past this position here. */
1380 ME_ScrollDown( editor, editor->sizeWindow.cy );
1381 /* Only move the cursor by the amount scrolled. */
1382 yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos;
1383 last_row = row;
1384
1385 while ((row = row_next_all_paras( row )))
1386 {
1387 if (row_para( row )->pt.y + row->pt.y >= yd) break;
1388 last_row = row;
1389 }
1390
1391 row_cursor( editor, last_row, x, cursor );
1392 }
1393}
ME_Paragraph * editor_end_para(ME_TextEditor *editor)
Definition: editor.c:282
void ME_ScrollDown(ME_TextEditor *editor, int cy)
Definition: paint.c:1136
LONG cy
Definition: kdterminal.h:28

Referenced by ME_ArrowKey().

◆ ME_ArrowPageUp()

static void ME_ArrowPageUp ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1331 of file caret.c.

1332{
1333 ME_Row *row = para_first_row( editor_first_para( editor ) ), *last_row;
1334 int x, yd, old_scroll_pos = editor->vert_si.nPos;
1335
1336 if (editor->vert_si.nPos < row->nHeight)
1337 {
1338 ME_SetCursorToStart( editor, cursor );
1339 /* Native clears seems to clear this x value on page up at the top
1340 * of the text, but not on page down at the end of the text.
1341 * Doesn't make sense, but we try to be bug for bug compatible. */
1342 editor->nUDArrowX = -1;
1343 }
1344 else
1345 {
1346 x = ME_GetXForArrow( editor, cursor );
1348
1349 ME_ScrollUp( editor, editor->sizeWindow.cy );
1350 /* Only move the cursor by the amount scrolled. */
1351 yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos;
1352 last_row = row;
1353
1354 while ((row = row_prev_all_paras( row )))
1355 {
1356 if (row_para( row )->pt.y + row->pt.y < yd) break;
1357 last_row = row;
1358 }
1359
1360 row_cursor( editor, last_row, x, cursor );
1361 }
1362}
void ME_ScrollUp(ME_TextEditor *editor, int cy)
Definition: paint.c:1131

Referenced by ME_ArrowKey().

◆ ME_DeleteSelection()

void ME_DeleteSelection ( ME_TextEditor editor)

Definition at line 1425 of file caret.c.

1426{
1427 LONG from, to;
1428 int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
1429 int nEndCursor = nStartCursor ^ 1;
1430 ME_DeleteTextAtCursor(editor, nStartCursor, to - from);
1431 editor->pCursors[nEndCursor] = editor->pCursors[nStartCursor];
1432}
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
Definition: caret.c:481
int ME_GetSelectionOfs(ME_TextEditor *editor, LONG *from, LONG *to)
Definition: caret.c:42
long LONG
Definition: pedump.c:60
CardRegion * from
Definition: spigame.cpp:19

Referenced by editor_handle_message(), editor_insert_oleobj(), ME_InsertEndRowFromCursor(), ME_InsertTextFromCursor(), and ME_KeyDown().

◆ ME_DeleteTextAtCursor()

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

Definition at line 481 of file caret.c.

482{
483 assert(nCursor>=0 && nCursor<editor->nCursors);
484 /* text operations set modified state */
485 editor->nModifyStep = 1;
486 return ME_InternalDeleteText(editor, &editor->pCursors[nCursor],
487 nChars, FALSE);
488}
BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce)
Definition: caret.c:339

Referenced by ME_DeleteSelection(), and ME_KeyDown().

◆ ME_ExtendAnchorSelection()

static void ME_ExtendAnchorSelection ( ME_TextEditor editor)
static

Definition at line 1088 of file caret.c.

1089{
1090 ME_Cursor tmp_cursor;
1091 int curOfs, anchorStartOfs, anchorEndOfs;
1092 if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument)
1093 return;
1094 curOfs = ME_GetCursorOfs(&editor->pCursors[0]);
1095 anchorStartOfs = ME_GetCursorOfs(&editor->pCursors[3]);
1096 anchorEndOfs = ME_GetCursorOfs(&editor->pCursors[2]);
1097
1098 tmp_cursor = editor->pCursors[0];
1099 editor->pCursors[0] = editor->pCursors[2];
1100 editor->pCursors[1] = editor->pCursors[3];
1101 if (curOfs < anchorStartOfs)
1102 {
1103 /* Extend the left side of selection */
1104 editor->pCursors[1] = tmp_cursor;
1105 switch (editor->nSelectionType)
1106 {
1107 case stWord:
1108 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
1109 break;
1110
1111 case stLine:
1112 {
1113 ME_Row *row = row_from_cursor( editor->pCursors + 1 );
1114 row_first_cursor( row, editor->pCursors + 1 );
1115 break;
1116 }
1117
1118 case stParagraph:
1119 editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
1120 editor->pCursors[1].nOffset = 0;
1121 break;
1122
1123 default:
1124 break;
1125 }
1126 }
1127 else if (curOfs >= anchorEndOfs)
1128 {
1129 /* Extend the right side of selection */
1130 editor->pCursors[0] = tmp_cursor;
1131 switch (editor->nSelectionType)
1132 {
1133 case stWord:
1134 ME_MoveCursorWords( editor, &editor->pCursors[0], +1 );
1135 break;
1136
1137 case stLine:
1138 {
1139 ME_Row *row = row_from_cursor( editor->pCursors );
1140 row_end_cursor( row, editor->pCursors, TRUE );
1141 break;
1142 }
1143
1144 case stParagraph:
1145 editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
1146 editor->pCursors[0].para = editor->pCursors[0].run->para;
1147 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
1148 break;
1149
1150 default:
1151 break;
1152 }
1153 }
1154}
int ME_GetCursorOfs(const ME_Cursor *cursor)
Definition: caret.c:923
ME_Run * para_end_run(ME_Paragraph *para)
Definition: para.c:117
ME_Run * para_first_run(ME_Paragraph *para)
Definition: para.c:104
@ stWord
Definition: editstr.h:364
@ stParagraph
Definition: editstr.h:366
@ stPosition
Definition: editstr.h:363
@ stLine
Definition: editstr.h:365
@ stDocument
Definition: editstr.h:367
ME_Paragraph * para
Definition: editstr.h:275
int nOffset
Definition: editstr.h:277
ME_Run * run
Definition: editstr.h:276
struct tagME_Paragraph * para
Definition: editstr.h:161
int len
Definition: editstr.h:163
ME_SelectionType nSelectionType
Definition: editstr.h:443

Referenced by ME_LButtonDown(), and ME_MouseMove().

◆ 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_GetSelectionCharFormat(), ME_SetSelectionCharFormat(), ME_StreamIn(), ME_UpdateSelectionLinkAttribute(), and style_get_insert_style().

◆ ME_GetSelectionInsertStyle()

ME_Style * ME_GetSelectionInsertStyle ( ME_TextEditor editor)

Definition at line 1434 of file caret.c.

1435{
1436 return style_get_insert_style( editor, editor->pCursors );
1437}

Referenced by editor_handle_message(), 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->props & TXTBIT_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: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define E_INVALIDARG
Definition: ddrawi.h:101
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2146
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#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:601
unsigned int bEmulateVersion10
Definition: editstr.h:392
#define TXTBIT_MULTILINE
Definition: textserv.h:186

Referenced by editor_handle_message().

◆ ME_GetXForArrow()

static int ME_GetXForArrow ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1248 of file caret.c.

1249{
1250 ME_Run *run = pCursor->run;
1251 int x;
1252
1253 if (editor->nUDArrowX != -1)
1254 x = editor->nUDArrowX;
1255 else
1256 {
1257 x = run->pt.x;
1258 x += ME_PointFromChar( editor, run, pCursor->nOffset, TRUE );
1259 editor->nUDArrowX = x;
1260 }
1261 return x;
1262}
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order)
Definition: run.c:654

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

◆ ME_InsertEndRowFromCursor()

void ME_InsertEndRowFromCursor ( ME_TextEditor editor,
int  nCursor 
)

Definition at line 568 of file caret.c.

569{
570 const WCHAR space = ' ';
571 ME_Cursor *cursor = editor->pCursors + nCursor;
573
574 /* FIXME no no no */
575 if (ME_IsSelection(editor))
576 ME_DeleteSelection(editor);
577
578 run_insert( editor, cursor, style, &space, 1, MERF_ENDROW );
579
581}
#define MERF_ENDROW
Definition: editstr.h:122

Referenced by handle_enter(), and SpecialChar().

◆ ME_InsertTextFromCursor()

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

Definition at line 584 of file caret.c.

586{
587 const WCHAR *pos;
588 ME_Cursor *cursor = editor->pCursors + nCursor;
589 int oldLen;
590
591 /* FIXME really HERE ? */
592 if (ME_IsSelection(editor))
593 ME_DeleteSelection(editor);
594
595 oldLen = ME_GetTextLength(editor);
596
597 /* text operations set modified state */
598 editor->nModifyStep = 1;
599
600 assert(style);
601
602 if (len == -1) len = lstrlenW( str );
603
604 /* grow the text limit to fit our text */
605 if (editor->nTextLimit < oldLen + len) editor->nTextLimit = oldLen + len;
606
607 pos = str;
608
609 while (len)
610 {
611 /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
612 while (pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t')
613 pos++;
614
615 if (pos != str) /* handle text */
616 run_insert( editor, cursor, style, str, pos - str, 0 );
617 else if (*pos == '\t') /* handle tabs */
618 {
619 const WCHAR tab = '\t';
620 run_insert( editor, cursor, style, &tab, 1, MERF_TAB );
621 pos++;
622 }
623 else /* handle EOLs */
624 {
625 ME_Run *end_run, *run, *prev;
626 ME_Paragraph *new_para;
627 int eol_len = 0;
628
629 /* Check if new line is allowed for this control */
630 if (!(editor->props & TXTBIT_MULTILINE))
631 break;
632
633 /* Find number of CR and LF in end of paragraph run */
634 if (*pos =='\r')
635 {
636 if (len > 1 && pos[1] == '\n')
637 eol_len = 2;
638 else if (len > 2 && pos[1] == '\r' && pos[2] == '\n')
639 eol_len = 3;
640 else
641 eol_len = 1;
642 }
643 else
644 {
645 assert(*pos == '\n');
646 eol_len = 1;
647 }
648 pos += eol_len;
649
650 if (!editor->bEmulateVersion10 && eol_len == 3)
651 {
652 /* handle special \r\r\n sequence (richedit 2.x and higher only) */
653 const WCHAR space = ' ';
654 run_insert( editor, cursor, style, &space, 1, 0 );
655 }
656 else
657 {
658 const WCHAR cr = '\r', *eol_str = str;
659
660 if (!editor->bEmulateVersion10)
661 {
662 eol_str = &cr;
663 eol_len = 1;
664 }
665
666 if (cursor->nOffset == cursor->run->len)
667 {
668 run = run_next( cursor->run );
669 if (!run) run = cursor->run;
670 }
671 else
672 {
673 if (cursor->nOffset) run_split( editor, cursor );
674 run = cursor->run;
675 }
676
677 new_para = para_split( editor, run, style, eol_str, eol_len, 0 );
678 end_run = para_end_run( para_prev( new_para ) );
679
680 /* Move any cursors that were at the end of the previous run to the beginning of the new para */
681 prev = run_prev( end_run );
682 if (prev)
683 {
684 int i;
685 for (i = 0; i < editor->nCursors; i++)
686 {
687 if (editor->pCursors[i].run == prev &&
688 editor->pCursors[i].nOffset == prev->len)
689 {
690 editor->pCursors[i].para = new_para;
691 editor->pCursors[i].run = run;
692 editor->pCursors[i].nOffset = 0;
693 }
694 }
695 }
696
697 }
698 }
699 len -= pos - str;
700 str = pos;
701 }
702}
#define lstrlenW
Definition: compat.h:750
ME_Run * run_next(ME_Run *run)
Definition: run.c:68
ME_Paragraph * para_split(ME_TextEditor *editor, ME_Run *run, ME_Style *style, const WCHAR *eol_str, int eol_len, int paraFlags)
Definition: para.c:538
ME_Run * run_split(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: run.c:310
#define MERF_TAB
Definition: editstr.h:105
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
static struct wctab tab[]

Referenced by editor_handle_message(), fnTextSrv_TxSetText(), handle_enter(), handle_wm_char(), ITextRange_fnSetText(), ME_ReplaceSel(), ME_RTFParAttrHook(), ME_RTFSpecialCharHook(), ME_SetText(), ME_StreamInText(), RTFFlushUnicodeOutputBuffer(), and table_append_row().

◆ ME_InternalDeleteText()

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

Definition at line 339 of file caret.c.

341{
342 ME_Cursor c = *start;
343 int nOfs = ME_GetCursorOfs(start), text_len = ME_GetTextLength( editor );
344 int shift = 0;
345 int totalChars = nChars;
346 ME_Paragraph *start_para;
347 BOOL delete_all = FALSE;
348
349 /* Prevent deletion past last end of paragraph run. */
350 nChars = min(nChars, text_len - nOfs);
351 if (nChars == text_len) delete_all = TRUE;
352 start_para = c.para;
353
354 if (!bForce)
355 {
356 table_protect_partial_deletion( editor, &c, &nChars );
357 if (nChars == 0) return FALSE;
358 }
359
360 while (nChars > 0)
361 {
362 ME_Run *run;
363 cursor_from_char_ofs( editor, nOfs + nChars, &c );
364 if (!c.nOffset)
365 {
366 /* We aren't deleting anything in this run, so we will go back to the
367 * last run we are deleting text in. */
368 c.run = run_prev_all_paras( c.run );
369 c.para = c.run->para;
370 c.nOffset = c.run->len;
371 }
372 run = c.run;
373 if (run->nFlags & MERF_ENDPARA)
374 {
375 int eollen = c.run->len;
376 BOOL keepFirstParaFormat;
377
378 if (!para_next( para_next( c.para ) )) return TRUE;
379
380 keepFirstParaFormat = (totalChars == nChars && nChars <= eollen &&
381 run->nCharOfs);
382 if (!editor->bEmulateVersion10) /* v4.1 */
383 {
384 ME_Paragraph *this_para = run->para;
385 ME_Paragraph *next_para = para_next( this_para );
386
387 /* The end of paragraph before a table row is only deleted if there
388 * is nothing else on the line before it. */
389 if (this_para == start_para && next_para->nFlags & MEPF_ROWSTART)
390 {
391 /* If the paragraph will be empty, then it should be deleted, however
392 * it still might have text right now which would inherit the
393 * MEPF_STARTROW property if we joined it right now.
394 * Instead we will delete it after the preceding text is deleted. */
395 if (nOfs > this_para->nCharOfs)
396 {
397 /* Skip this end of line. */
398 nChars -= (eollen < nChars) ? eollen : nChars;
399 continue;
400 }
401 keepFirstParaFormat = TRUE;
402 }
403 }
404 para_join( editor, c.para, keepFirstParaFormat );
405 /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
406 ME_CheckCharOffsets(editor);
407 nChars -= (eollen < nChars) ? eollen : nChars;
408 continue;
409 }
410 else
411 {
413 int nCharsToDelete = min(nChars, c.nOffset);
414 int i;
415
416 c.nOffset -= nCharsToDelete;
417
418 para_mark_rewrap( editor, c.run->para );
419
420 cursor = c;
421 /* nChars is the number of characters that should be deleted from the
422 PRECEDING runs (these BEFORE cursor.pRun)
423 nCharsToDelete is a number of chars to delete from THIS run */
424 nChars -= nCharsToDelete;
425 shift -= nCharsToDelete;
426 TRACE("Deleting %d (remaining %d) chars at %d in %s (%d)\n",
427 nCharsToDelete, nChars, c.nOffset,
428 debugstr_run( run ), run->len);
429
430 /* nOfs is a character offset (from the start of the document
431 to the current (deleted) run */
432 add_undo_insert_run( editor, nOfs + nChars, get_text( run, c.nOffset ), nCharsToDelete, run->nFlags, run->style );
433
434 ME_StrDeleteV(run->para->text, run->nCharOfs + c.nOffset, nCharsToDelete);
435 run->len -= nCharsToDelete;
436 TRACE("Post deletion string: %s (%d)\n", debugstr_run( run ), run->len);
437 TRACE("Shift value: %d\n", shift);
438
439 /* update cursors (including c) */
440 for (i=-1; i<editor->nCursors; i++) {
441 ME_Cursor *pThisCur = editor->pCursors + i;
442 if (i == -1) pThisCur = &c;
443 if (pThisCur->run == cursor.run) {
444 if (pThisCur->nOffset > cursor.nOffset) {
445 if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete)
446 pThisCur->nOffset = cursor.nOffset;
447 else
448 pThisCur->nOffset -= nCharsToDelete;
449 assert(pThisCur->nOffset >= 0);
450 assert(pThisCur->nOffset <= run->len);
451 }
452 if (pThisCur->nOffset == run->len)
453 {
454 pThisCur->run = run_next( pThisCur->run );
455 assert( pThisCur->run );
456 pThisCur->nOffset = 0;
457 }
458 }
459 }
460
461 /* c = updated data now */
462
463 if (c.run == cursor.run) c.run->nCharOfs -= shift;
464 editor_propagate_char_ofs( editor, NULL, c.run, shift );
465
466 if (!cursor.run->len)
467 {
468 TRACE("Removing empty run\n");
469 ME_Remove( run_get_di( cursor.run ));
471 }
472
473 shift = 0;
474 continue;
475 }
476 }
477 if (delete_all) editor_set_default_para_fmt( editor, &start_para->fmt );
478 return TRUE;
479}
void editor_set_default_para_fmt(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
Definition: para.c:958
void ME_Remove(ME_DisplayItem *diWhere)
Definition: list.c:35
void editor_propagate_char_ofs(ME_TextEditor *editor, ME_Paragraph *para, ME_Run *run, int shift)
Definition: run.c:147
static ME_DisplayItem * run_get_di(ME_Run *run)
Definition: editor.h:162
ME_Paragraph * para_join(ME_TextEditor *editor, ME_Paragraph *para, BOOL use_first_fmt)
Definition: para.c:681
void table_protect_partial_deletion(ME_TextEditor *editor, ME_Cursor *c, int *num_chars)
Definition: table.c:217
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars)
Definition: string.c:147
void para_mark_rewrap(ME_TextEditor *editor, ME_Paragraph *para)
Definition: para.c:26
BOOL add_undo_insert_run(ME_TextEditor *, int pos, const WCHAR *str, int len, int flags, ME_Style *style)
Definition: undo.c:131
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
void ME_DestroyDisplayItem(ME_DisplayItem *item)
Definition: list.c:115
static const char * debugstr_run(const ME_Run *run)
Definition: editor.h:46
#define MERF_ENDPARA
Definition: editstr.h:120
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
PARAFORMAT2 fmt
Definition: editstr.h:204
int nCharOfs
Definition: editstr.h:162
ME_Style * style
Definition: editstr.h:160
int nFlags
Definition: editstr.h:165

Referenced by editor_copy_or_cut(), editor_handle_message(), fnTextSrv_TxSetText(), ITextRange_fnSetText(), ME_DeleteTextAtCursor(), ME_PlayUndoItem(), ME_ReplaceSel(), ME_RTFSpecialCharHook(), and ME_StreamIn().

◆ ME_IsSelection()

◆ ME_LButtonDown()

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

Definition at line 1156 of file caret.c.

1157{
1158 ME_Cursor tmp_cursor;
1159 BOOL is_selection = FALSE, is_shift;
1160
1161 editor->nUDArrowX = -1;
1162
1163 x += editor->horz_si.nPos;
1164 y += editor->vert_si.nPos;
1165
1166 tmp_cursor = editor->pCursors[0];
1167 is_selection = ME_IsSelection(editor);
1168 is_shift = GetKeyState(VK_SHIFT) < 0;
1169
1170 cursor_from_virtual_coords( editor, x, y, &editor->pCursors[0], FALSE );
1171
1172 if (x >= editor->rcFormat.left || is_shift)
1173 {
1174 if (clickNum > 1)
1175 {
1176 editor->pCursors[1] = editor->pCursors[0];
1177 if (is_shift) {
1178 if (x >= editor->rcFormat.left)
1179 ME_SelectByType(editor, stWord);
1180 else
1182 } else if (clickNum % 2 == 0) {
1183 ME_SelectByType(editor, stWord);
1184 } else {
1186 }
1187 }
1188 else if (!is_shift)
1189 {
1190 editor->nSelectionType = stPosition;
1191 editor->pCursors[1] = editor->pCursors[0];
1192 }
1193 else if (!is_selection)
1194 {
1195 editor->nSelectionType = stPosition;
1196 editor->pCursors[1] = tmp_cursor;
1197 }
1198 else if (editor->nSelectionType != stPosition)
1199 {
1201 }
1202 }
1203 else
1204 {
1205 if (clickNum < 2) {
1206 ME_SelectByType(editor, stLine);
1207 } else if (clickNum % 2 == 0 || is_shift) {
1209 } else {
1210 ME_SelectByType(editor, stDocument);
1211 }
1212 }
1213 ME_InvalidateSelection(editor);
1214 update_caret(editor);
1215 ME_SendSelChange(editor);
1216}
static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
Definition: caret.c:1088
static void ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
Definition: caret.c:875
#define VK_SHIFT
Definition: winuser.h:2238
SHORT WINAPI GetKeyState(_In_ int)

Referenced by editor_handle_message().

◆ ME_MouseMove()

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

Definition at line 1218 of file caret.c.

1219{
1220 ME_Cursor tmp_cursor;
1221
1222 if (editor->nSelectionType == stDocument)
1223 return;
1224 x += editor->horz_si.nPos;
1225 y += editor->vert_si.nPos;
1226
1227 tmp_cursor = editor->pCursors[0];
1228 /* FIXME: do something with the return value of cursor_from_virtual_coords */
1229 cursor_from_virtual_coords( editor, x, y, &tmp_cursor, TRUE );
1230
1231 ME_InvalidateSelection(editor);
1232 editor->pCursors[0] = tmp_cursor;
1234
1235 if (editor->nSelectionType != stPosition &&
1236 memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor)))
1237 /* The scroll the cursor towards the other end, since it was the one
1238 * extended by ME_ExtendAnchorSelection */
1239 editor_ensure_visible( editor, &editor->pCursors[1] );
1240 else
1241 editor_ensure_visible( editor, &editor->pCursors[0] );
1242
1243 ME_InvalidateSelection(editor);
1244 update_caret(editor);
1245 ME_SendSelChange(editor);
1246}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112

Referenced by editor_handle_message().

◆ ME_MoveCursorChars()

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

Definition at line 709 of file caret.c.

710{
711 cursor->nOffset += nRelOfs;
712 if (cursor->nOffset < 0)
713 {
714 cursor->nOffset += cursor->run->nCharOfs;
715 if (cursor->nOffset >= 0)
716 {
717 /* new offset in the same paragraph */
718 do {
719 cursor->run = run_prev( cursor->run );
720 } while (cursor->nOffset < cursor->run->nCharOfs);
721 cursor->nOffset -= cursor->run->nCharOfs;
722 return nRelOfs;
723 }
724
725 cursor->nOffset += cursor->para->nCharOfs;
726 if (cursor->nOffset <= 0)
727 {
728 /* moved to the start of the text */
729 nRelOfs -= cursor->nOffset;
731 return nRelOfs;
732 }
733
734 /* new offset in a previous paragraph */
735 do {
736 cursor->para = para_prev( cursor->para );
737 } while (cursor->nOffset < cursor->para->nCharOfs);
738 cursor->nOffset -= cursor->para->nCharOfs;
739
740 cursor->run = para_end_run( cursor->para );
741 while (cursor->nOffset < cursor->run->nCharOfs)
742 cursor->run = run_prev( cursor->run );
743 cursor->nOffset -= cursor->run->nCharOfs;
744 }
745 else if (cursor->nOffset >= cursor->run->len)
746 {
747 ME_Paragraph *next_para;
748 int new_offset;
749
750 new_offset = ME_GetCursorOfs(cursor);
751 next_para = para_next( cursor->para );
752 if (new_offset < next_para->nCharOfs)
753 {
754 /* new offset in the same paragraph */
755 do {
756 cursor->nOffset -= cursor->run->len;
757 cursor->run = run_next( cursor->run );
758 } while (cursor->nOffset >= cursor->run->len);
759 return nRelOfs;
760 }
761
762 if (new_offset >= ME_GetTextLength(editor) + (final_eop ? 1 : 0))
763 {
764 /* new offset at the end of the text */
765 ME_SetCursorToEnd(editor, cursor, final_eop);
766 nRelOfs -= new_offset - (ME_GetTextLength(editor) + (final_eop ? 1 : 0));
767 return nRelOfs;
768 }
769
770 /* new offset in a following paragraph */
771 do {
772 cursor->para = next_para;
773 next_para = para_next( next_para );
774 } while (new_offset >= next_para->nCharOfs);
775
776 cursor->nOffset = new_offset - cursor->para->nCharOfs;
777 cursor->run = para_first_run( cursor->para );
778 while (cursor->nOffset >= cursor->run->len)
779 {
780 cursor->nOffset -= cursor->run->len;
781 cursor->run = run_next( cursor->run );
782 }
783 } /* else new offset is in the same run */
784 return nRelOfs;
785}

Referenced by get_textfont_prop_for_pos(), ME_ArrowKey(), ME_FindText(), ME_PlayUndoItem(), ME_StreamIn(), ME_StreamOutRTF(), set_selection_cursors(), table_protect_partial_deletion(), textrange_endof(), textrange_move(), textrange_moveend(), and textrange_movestart().

◆ ME_MoveCursorWords()

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

Definition at line 789 of file caret.c.

790{
791 ME_Run *run = cursor->run, *other_run;
792 ME_Paragraph *para = cursor->para;
793 int nOffset = cursor->nOffset;
794
795 if (nRelOfs == -1)
796 {
797 /* Backward movement */
798 while (TRUE)
799 {
800 nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDLEFT );
801 if (nOffset) break;
802 other_run = run_prev( run );
803 if (other_run)
804 {
805 if (ME_CallWordBreakProc( editor, get_text( other_run, 0 ), other_run->len, other_run->len - 1, WB_ISDELIMITER )
806 && !(run->nFlags & MERF_ENDPARA)
807 && !(cursor->run == run && cursor->nOffset == 0)
808 && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, 0, WB_ISDELIMITER ))
809 break;
810 run = other_run;
811 nOffset = other_run->len;
812 }
813 else
814 {
815 if (cursor->run == run && cursor->nOffset == 0)
816 {
817 para = run->para;
818 /* Skip empty start of table row paragraph */
819 if (para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART)
820 para = para_prev( para );
821 /* Paragraph breaks are treated as separate words */
822 if (!para_prev( para )) return FALSE;
823 para = para_prev( para );
824 run = para_end_run( para );
825 }
826 break;
827 }
828 }
829 }
830 else
831 {
832 /* Forward movement */
833 BOOL last_delim = FALSE;
834
835 while (TRUE)
836 {
837 if (last_delim && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_ISDELIMITER ))
838 break;
839 nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDRIGHT );
840 if (nOffset < run->len) break;
841 other_run = run_next( run );
842 if (other_run)
843 {
844 last_delim = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset - 1, WB_ISDELIMITER );
845 run = other_run;
846 nOffset = 0;
847 }
848 else
849 {
850 ME_Paragraph *other_para = para_next( para );
851 if (!para_next( other_para ))
852 {
853 if (cursor->run == run) return FALSE;
854 nOffset = 0;
855 break;
856 }
857 if (other_para->nFlags & MEPF_ROWSTART) other_para = para_next( other_para );
858 if (cursor->run == run) {
859 para = other_para;
860 run = para_first_run( para );
861 }
862 nOffset = 0;
863 break;
864 }
865 }
866 }
867 cursor->para = para;
868 cursor->run = run;
869 cursor->nOffset = nOffset;
870 return TRUE;
871}
int ME_CallWordBreakProc(ME_TextEditor *editor, WCHAR *str, INT len, INT start, INT code)
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 875 of file caret.c.

876{
877 /* pCursor[0] is the end of the selection
878 * pCursor[1] is the start of the selection (or the position selection anchor)
879 * pCursor[2] and [3] are the selection anchors that are backed up
880 * so they are kept when the selection changes for drag selection.
881 */
882
883 editor->nSelectionType = selectionType;
884 switch(selectionType)
885 {
886 case stPosition:
887 break;
888 case stWord:
889 ME_MoveCursorWords(editor, &editor->pCursors[0], +1);
890 editor->pCursors[1] = editor->pCursors[0];
891 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
892 break;
893 case stParagraph:
894 editor->pCursors[1] = editor->pCursors[0];
895
896 editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
897 editor->pCursors[0].para = editor->pCursors[0].run->para;
898 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
899
900 editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
901 editor->pCursors[1].nOffset = 0;
902 break;
903 case stLine:
904 {
905 ME_Row *row = row_from_cursor( editor->pCursors );
906
907 row_first_cursor( row, editor->pCursors + 1 );
908 row_end_cursor( row, editor->pCursors, TRUE );
909 break;
910 }
911 case stDocument:
912 /* Select everything with cursor anchored from the start of the text */
913 ME_SetCursorToStart(editor, &editor->pCursors[1]);
914 ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE);
915 break;
916 default: assert(0);
917 }
918 /* Store the anchor positions for extending the selection. */
919 editor->pCursors[2] = editor->pCursors[0];
920 editor->pCursors[3] = editor->pCursors[1];
921}

Referenced by ME_LButtonDown().

◆ ME_SendSelChange()

void ME_SendSelChange ( ME_TextEditor editor)

Definition at line 1439 of file caret.c.

1440{
1441 SELCHANGE sc;
1442
1443 sc.nmhdr.hwndFrom = NULL;
1444 sc.nmhdr.idFrom = 0;
1445 sc.nmhdr.code = EN_SELCHANGE;
1446 ME_GetSelectionOfs(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
1447 sc.seltyp = SEL_EMPTY;
1448 if (sc.chrg.cpMin != sc.chrg.cpMax)
1449 sc.seltyp |= SEL_TEXT;
1450 if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */
1451 sc.seltyp |= SEL_MULTICHAR;
1452
1453 if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax)
1454 {
1455 ME_ClearTempStyle(editor);
1456
1457 editor->notified_cr = sc.chrg;
1458
1459 if (editor->nEventMask & ENM_SELCHANGE)
1460 {
1461 TRACE("cpMin=%ld cpMax=%ld seltyp=%d (%s %s)\n",
1462 sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,
1463 (sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "",
1464 (sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : "");
1465 ITextHost_TxNotify(editor->texthost, sc.nmhdr.code, &sc);
1466 }
1467 }
1468}
#define ITextHost_TxNotify(This, a, b)
Definition: editor.h:367
void ME_ClearTempStyle(ME_TextEditor *editor)
Definition: style.c:507
#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:446
UINT_PTR idFrom
Definition: winuser.h:3260
UINT code
Definition: winuser.h:3261
HWND hwndFrom
Definition: winuser.h:3259

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

◆ 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->para = para_prev( editor_end_para( editor ) );
37 cursor->run = para_end_run( cursor->para );
38 cursor->nOffset = final_eop ? cursor->run->len : 0;
39}

Referenced by cursor_from_virtual_coords(), cursor_move_line(), ME_ArrowCtrlEnd(), ME_ArrowPageDown(), ME_GetTextLength(), ME_MoveCursorChars(), ME_SelectByType(), and set_selection_cursors().

◆ ME_SetCursorToStart()

◆ pixel_pos_in_table_row()

static ME_Paragraph * pixel_pos_in_table_row ( int  x,
int  y,
ME_Paragraph para 
)
static

Definition at line 929 of file caret.c.

930{
931 ME_Cell *cell, *next_cell;
932
933 assert( para->nFlags & MEPF_ROWSTART );
934 cell = table_row_first_cell( para );
935 assert( cell );
936
937 /* find the cell we are in */
938 while ((next_cell = cell_next( cell )) != NULL)
939 {
940 if (x < next_cell->pt.x)
941 {
942 para = cell_first_para( cell );
943 /* Found the cell, but there might be multiple paragraphs in
944 * the cell, so need to search down the cell for the paragraph. */
945 while (cell == para_cell( para ))
946 {
947 if (y < para->pt.y + para->nHeight)
948 {
949 if (para->nFlags & MEPF_ROWSTART) return pixel_pos_in_table_row( x, y, para );
950 else return para;
951 }
952 para = para_next( para );
953 }
954 /* Past the end of the cell, so go back to the last cell paragraph */
955 return para_prev( para );
956 }
957 cell = next_cell;
958 }
959 /* Return table row delimiter */
960 para = table_row_end( para );
961 assert( para->nFlags & MEPF_ROWEND );
964 return para;
965}
#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

Referenced by cursor_from_virtual_coords(), and pixel_pos_in_table_row().

◆ row_cursor()

static BOOL row_cursor ( ME_TextEditor editor,
ME_Row row,
int  x,
ME_Cursor cursor 
)
static

Definition at line 967 of file caret.c.

969{
970 ME_Run *run, *last;
971 BOOL exact = TRUE;
972
973 if (x < row->pt.x)
974 {
975 x = row->pt.x;
976 exact = FALSE;
977 }
978
979 run = row_first_run( row );
980 assert( run );
981 cursor->nOffset = 0;
982 do
983 {
984 if (x >= run->pt.x && x < run->pt.x + run->nWidth)
985 {
986 cursor->nOffset = ME_CharFromPoint( editor, x - run->pt.x, run, TRUE, TRUE );
987 cursor->run = run;
988 cursor->para = run->para;
989 return exact;
990 }
991 last = run;
992 run = row_next_run( row, run );
993 } while (run);
994
995 run = last;
996
997 cursor->run = run;
998 cursor->para = run->para;
999 return FALSE;
1000}
ME_Run * row_first_run(ME_Row *row)
Definition: row.c:54
ME_Run * row_next_run(ME_Row *row, ME_Run *run)
Definition: row.c:63
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order)
Definition: run.c:575
static UINT UINT last
Definition: font.c:45
int nWidth
Definition: editstr.h:164

Referenced by cursor_from_virtual_coords(), cursor_move_line(), ME_ArrowPageDown(), and ME_ArrowPageUp().

◆ 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 LONG 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 cursor_from_char_ofs( 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].run->nFlags & MERF_ENDPARA)
209 editor->pCursors[1].nOffset = 0;
210 if (editor->pCursors[0].run->nFlags & MERF_ENDPARA)
211 {
212 if (to > len)
213 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
214 else
215 editor->pCursors[0].nOffset = 0;
216 }
217 return to;
218}
GLuint GLuint end
Definition: gl.h:1545

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

◆ show_caret()

void show_caret ( ME_TextEditor editor)

Definition at line 261 of file caret.c.

262{
264 editor->caret_hidden = FALSE;
265}

Referenced by update_caret().

◆ update_caret()

void update_caret ( ME_TextEditor editor)

Definition at line 277 of file caret.c.

278{
279 int x, y, height;
280
281 if (!editor->bHaveFocus) return;
282 if (!ME_IsSelection(editor))
283 {
284 cursor_coords( editor, &editor->pCursors[0], &x, &y, &height );
285 if (height != editor->caret_height) create_caret(editor);
286 x = min(x, editor->rcFormat.right-1);
288 show_caret(editor);
289 }
290 else
291 hide_caret(editor);
292#ifdef __REACTOS__
294 {
295 HIMC hIMC = ImmGetContext(editor->hWnd);
296 if (hIMC)
297 {
299 LOGFONTW lf;
300 COMPOSITIONFORM CompForm;
301 POINT pt = { x, y };
302
303 CompForm.ptCurrentPos = pt;
304 if (editor->styleFlags & ES_MULTILINE)
305 {
306 CompForm.dwStyle = CFS_RECT;
307 CompForm.rcArea = editor->rcFormat;
308 }
309 else
310 {
311 CompForm.dwStyle = CFS_POINT;
312 SetRectEmpty(&CompForm.rcArea);
313 }
314 ImmSetCompositionWindow(hIMC, &CompForm);
315
316 fmt.cbSize = sizeof(fmt);
318
319 ZeroMemory(&lf, sizeof(lf));
321 if (fmt.dwMask & CFM_SIZE)
322 {
324 lf.lfHeight = -MulDiv(fmt.yHeight, GetDeviceCaps(hdc, LOGPIXELSY), 1440);
325 DeleteDC(hdc);
326 }
327 if (fmt.dwMask & CFM_CHARSET)
328 lf.lfCharSet = fmt.bCharSet;
329 if (fmt.dwMask & CFM_FACE)
330 lstrcpynW(lf.lfFaceName, fmt.szFaceName, ARRAY_SIZE(lf.lfFaceName));
331 ImmSetCompositionFontW(hIMC, &lf);
332
333 ImmReleaseContext(editor->hWnd, hIMC);
334 }
335 }
336#endif
337}
#define ARRAY_SIZE(A)
Definition: main.h:20
DWORD HIMC
Definition: dimm.idl:75
#define lstrcpynW
Definition: compat.h:738
void create_caret(ME_TextEditor *editor)
Definition: caret.c:251
void show_caret(ME_TextEditor *editor)
Definition: caret.c:261
#define ITextHost_TxSetCaretPos(This, a, b)
Definition: editor.h:342
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
Definition: run.c:858
BOOL WINAPI ImmSetCompositionFontW(_In_ HIMC hIMC, _In_ LPLOGFONTW lplf)
Definition: ime.c:1322
#define CFS_RECT
Definition: imm.h:324
BOOL WINAPI ImmSetCompositionWindow(_In_ HIMC hIMC, _In_ LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1149
HIMC WINAPI ImmGetContext(_In_ HWND hWnd)
Definition: imm.c:1065
#define CFS_POINT
Definition: imm.h:325
BOOL WINAPI ImmReleaseContext(_In_ HWND hWnd, _In_ HIMC hIMC)
Definition: imm.c:1109
BOOL WINAPI ImmIsIME(_In_ HKL hKL)
Definition: ime.c:429
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
#define ES_MULTILINE
Definition: pedump.c:667
#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
LONG right
Definition: windef.h:308
#define ZeroMemory
Definition: winbase.h:1753
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 editor_handle_message(), ME_ArrowKey(), ME_LButtonDown(), ME_MouseMove(), ME_UpdateRepaint(), set_selection(), and table_handle_tab().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( richedit  )