ReactOS 0.4.16-dev-905-gc1b8c4f
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 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)
 
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_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 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 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:341
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:384
ME_Cursor * pCursors
Definition: editstr.h:389
BOOL caret_hidden
Definition: editstr.h:445

Referenced by editor_handle_message(), and update_caret().

◆ create_re_object()

static struct re_object * create_re_object ( const REOBJECT reo)
static

Definition at line 490 of file caret.c.

491{
492 struct re_object *reobj = heap_alloc(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 return reobj;
501}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
#define WARN(fmt,...)
Definition: precomp.h:61
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN
Definition: richole.c:5829
REOBJECT obj
Definition: editstr.h:154

Referenced by ME_InsertOLEFromCursor().

◆ 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) DECLSPEC_HIDDEN
Definition: run.c:608
ME_Row * row_from_cursor(ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: row.c:74
#define ITextHost_TxGetDC(This)
Definition: editor.h:333
#define ITextHost_TxReleaseDC(This, a)
Definition: editor.h:334
ME_Run * run_prev(ME_Run *run) DECLSPEC_HIDDEN
Definition: run.c:82
#define MEPF_REWRAP
Definition: editstr.h:140
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:165
POINT pt
Definition: editstr.h:166
int nDescent
Definition: editstr.h:165
SCROLLINFO vert_si
Definition: editstr.h:440
SCROLLINFO horz_si
Definition: editstr.h:440
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48

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

◆ 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 978 of file caret.c.

980{
981 ME_Paragraph *para = editor_first_para( editor );
982 ME_Row *row = NULL, *next_row;
983 BOOL isExact = TRUE;
984
985 x -= editor->rcFormat.left;
986 y -= editor->rcFormat.top;
987
988 /* find paragraph */
989 for (; para_next( para ); para = para_next( para ))
990 {
991 if (y < para->pt.y + para->nHeight)
992 {
993 if (para->nFlags & MEPF_ROWSTART)
994 para = pixel_pos_in_table_row( x, y, para );
995 y -= para->pt.y;
996 row = para_first_row( para );
997 break;
998 }
999 else if (para->nFlags & MEPF_ROWSTART)
1000 {
1001 para = table_row_end( para );
1002 }
1003 }
1004 /* find row */
1005 while (row)
1006 {
1007 if (y < row->pt.y + row->nHeight) break;
1008 next_row = row_next( row );
1009 if (!next_row) break;
1010 row = next_row;
1011 }
1012
1013 if (!row && !final_eop && para_prev( para ))
1014 {
1015 /* The position is below the last paragraph, so the last row will be used
1016 * rather than the end of the text, so the x position will be used to
1017 * determine the offset closest to the pixel position. */
1018 isExact = FALSE;
1019 row = para_end_row( para_prev( para ) );
1020 }
1021
1022 if (row) return row_cursor( editor, row, x, result ) && isExact;
1023
1024 ME_SetCursorToEnd(editor, result, TRUE);
1025 return FALSE;
1026}
#define FALSE
Definition: types.h:117
static BOOL row_cursor(ME_TextEditor *editor, ME_Row *row, int x, ME_Cursor *cursor)
Definition: caret.c:933
static ME_Paragraph * pixel_pos_in_table_row(int x, int y, ME_Paragraph *para)
Definition: caret.c:895
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:279
#define pt(x, y)
Definition: drawing.c:79
ME_Row * para_first_row(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:132
ME_Row * para_end_row(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:141
ME_Row * row_next(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:27
ME_Paragraph * para_next(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:57
ME_Paragraph * para_prev(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:63
ME_Paragraph * table_row_end(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:127
#define MEPF_ROWSTART
Definition: editstr.h:143
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 ME_CharFromPos(), 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 1246 of file caret.c.

1247{
1248 ME_Paragraph *old_para = cursor->para, *new_para;
1250 int x = ME_GetXForArrow( editor, cursor );
1251
1252 if (up)
1253 {
1254 /* start of the previous row */
1256 if (!row)
1257 {
1258 if (extend) ME_SetCursorToStart( editor, cursor );
1259 return;
1260 }
1261 new_para = row_para( row );
1262 if (old_para->nFlags & MEPF_ROWEND ||
1263 (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para )))
1264 {
1265 /* Brought out of a cell */
1266 new_para = para_prev( table_row_start( old_para ));
1267 if (!new_para) return; /* At the top, so don't go anywhere. */
1268 row = para_first_row( new_para );
1269 }
1270 if (new_para->nFlags & MEPF_ROWEND)
1271 {
1272 /* Brought into a table row */
1273 ME_Cell *cell = table_row_end_cell( new_para );
1274 while (x < cell->pt.x && cell_prev( cell ))
1275 cell = cell_prev( cell );
1276 if (cell_next( cell )) /* else - we are still at the end of the row */
1277 row = para_end_row( cell_end_para( cell ) );
1278 }
1279 }
1280 else
1281 {
1282 /* start of the next row */
1284 if (!row)
1285 {
1286 if (extend) ME_SetCursorToEnd( editor, cursor, TRUE );
1287 return;
1288 }
1289 new_para = row_para( row );
1290 if (old_para->nFlags & MEPF_ROWSTART ||
1291 (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para )))
1292 {
1293 /* Brought out of a cell */
1294 new_para = para_next( table_row_end( old_para ) );
1295 if (!para_next( new_para )) return; /* At the bottom, so don't go anywhere. */
1296 row = para_first_row( new_para );
1297 }
1298 if (new_para->nFlags & MEPF_ROWSTART)
1299 {
1300 /* Brought into a table row */
1301 ME_Cell *cell = table_row_first_cell( new_para );
1302 while (cell_next( cell ) && x >= cell_next( cell )->pt.x)
1303 cell = cell_next( cell );
1304 row = para_first_row( cell_first_para( cell ) );
1305 }
1306 }
1307 if (!row) return;
1308
1309 row_cursor( editor, row, x, cursor );
1310}
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:1229
ME_Paragraph * cell_end_para(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:207
ME_Cell * para_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:127
ME_Paragraph * table_row_start(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:142
ME_Cell * table_row_first_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:170
ME_Paragraph * cell_first_para(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:202
ME_Row * row_next_all_paras(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:36
ME_Cell * cell_next(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:192
ME_Cell * table_row_end_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:178
ME_Cell * cell_prev(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:197
ME_Row * row_prev_all_paras(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:45
ME_Paragraph * row_para(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:103
#define MEPF_ROWEND
Definition: editstr.h:144
#define up(mutex)
Definition: glue.h:30

Referenced by ME_ArrowKey().

◆ 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:342

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 1395 of file caret.c.

1396{
1397 ME_SetCursorToEnd(editor, pCursor, FALSE);
1398}

Referenced by ME_ArrowKey().

◆ ME_ArrowCtrlHome()

static void ME_ArrowCtrlHome ( ME_TextEditor editor,
ME_Cursor pCursor 
)
static

Definition at line 1383 of file caret.c.

1384{
1385 ME_SetCursorToStart(editor, pCursor);
1386}

Referenced by ME_ArrowKey().

◆ ME_ArrowEnd()

static void ME_ArrowEnd ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1388 of file caret.c.

1389{
1391
1393}
void row_end_cursor(ME_Row *row, ME_Cursor *cursor, BOOL include_eop) DECLSPEC_HIDDEN
Definition: row.c:92

Referenced by ME_ArrowKey().

◆ ME_ArrowHome()

static void ME_ArrowHome ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1376 of file caret.c.

1377{
1379
1381}
void row_first_cursor(ME_Row *row, ME_Cursor *cursor) DECLSPEC_HIDDEN
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 1452 of file caret.c.

1453{
1454 int nCursor = 0;
1455 ME_Cursor *p = &editor->pCursors[nCursor];
1456 ME_Cursor tmp_curs = *p;
1457 BOOL success = FALSE;
1458
1459 ME_CheckCharOffsets(editor);
1460 switch(nVKey) {
1461 case VK_LEFT:
1462 if (ctrl)
1463 success = ME_MoveCursorWords(editor, &tmp_curs, -1);
1464 else
1465 success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend);
1466 break;
1467 case VK_RIGHT:
1468 if (ctrl)
1469 success = ME_MoveCursorWords(editor, &tmp_curs, +1);
1470 else
1471 success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend);
1472 break;
1473 case VK_UP:
1474 cursor_move_line( editor, &tmp_curs, TRUE, extend );
1475 break;
1476 case VK_DOWN:
1477 cursor_move_line( editor, &tmp_curs, FALSE, extend );
1478 break;
1479 case VK_PRIOR:
1480 ME_ArrowPageUp(editor, &tmp_curs);
1481 break;
1482 case VK_NEXT:
1483 ME_ArrowPageDown(editor, &tmp_curs);
1484 break;
1485 case VK_HOME: {
1486 if (ctrl)
1487 ME_ArrowCtrlHome(editor, &tmp_curs);
1488 else
1489 ME_ArrowHome(editor, &tmp_curs);
1490 break;
1491 }
1492 case VK_END:
1493 if (ctrl)
1494 ME_ArrowCtrlEnd(editor, &tmp_curs);
1495 else
1496 ME_ArrowEnd(editor, &tmp_curs);
1497 break;
1498 }
1499
1500 if (!extend)
1501 editor->pCursors[1] = tmp_curs;
1502 *p = tmp_curs;
1503
1504 ME_InvalidateSelection(editor);
1505 ME_Repaint(editor);
1506 hide_caret(editor);
1507 editor_ensure_visible( editor, &tmp_curs );
1508 update_caret(editor);
1509 ME_SendSelChange(editor);
1510 return success;
1511}
static void cursor_move_line(ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend)
Definition: caret.c:1246
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1376
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:678
BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
Definition: caret.c:758
void hide_caret(ME_TextEditor *editor)
Definition: caret.c:267
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1395
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1420
static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1312
static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1345
void update_caret(ME_TextEditor *editor)
Definition: caret.c:277
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1383
static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1388
void ME_CheckCharOffsets(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: run.c:173
void ME_InvalidateSelection(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:1247
void editor_ensure_visible(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: paint.c:1206
void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:119
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:2228
#define VK_NEXT
Definition: winuser.h:2224
#define VK_END
Definition: winuser.h:2225
#define VK_HOME
Definition: winuser.h:2226
#define VK_LEFT
Definition: winuser.h:2227
#define VK_RIGHT
Definition: winuser.h:2229
#define VK_DOWN
Definition: winuser.h:2230
#define VK_PRIOR
Definition: winuser.h:2223

Referenced by ME_KeyDown().

◆ ME_ArrowPageDown()

static void ME_ArrowPageDown ( ME_TextEditor editor,
ME_Cursor cursor 
)
static

Definition at line 1345 of file caret.c.

1346{
1347 ME_Row *row = para_end_row( para_prev( editor_end_para( editor ) ) ), *last_row;
1348 int x, yd, old_scroll_pos = editor->vert_si.nPos;
1349
1350 x = ME_GetXForArrow( editor, cursor );
1351
1352 if (editor->vert_si.nPos >= row_para( row )->pt.y + row->pt.y - editor->sizeWindow.cy)
1353 ME_SetCursorToEnd( editor, cursor, FALSE );
1354 else
1355 {
1357
1358 /* For native richedit controls:
1359 * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us
1360 * v4.1 can scroll past this position here. */
1361 ME_ScrollDown( editor, editor->sizeWindow.cy );
1362 /* Only move the cursor by the amount scrolled. */
1363 yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos;
1364 last_row = row;
1365
1366 while ((row = row_next_all_paras( row )))
1367 {
1368 if (row_para( row )->pt.y + row->pt.y >= yd) break;
1369 last_row = row;
1370 }
1371
1372 row_cursor( editor, last_row, x, cursor );
1373 }
1374}
ME_Paragraph * editor_end_para(ME_TextEditor *editor)
Definition: editor.c:285
void ME_ScrollDown(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN
Definition: paint.c:1132
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 1312 of file caret.c.

1313{
1314 ME_Row *row = para_first_row( editor_first_para( editor ) ), *last_row;
1315 int x, yd, old_scroll_pos = editor->vert_si.nPos;
1316
1317 if (editor->vert_si.nPos < row->nHeight)
1318 {
1319 ME_SetCursorToStart( editor, cursor );
1320 /* Native clears seems to clear this x value on page up at the top
1321 * of the text, but not on page down at the end of the text.
1322 * Doesn't make sense, but we try to be bug for bug compatible. */
1323 editor->nUDArrowX = -1;
1324 }
1325 else
1326 {
1327 x = ME_GetXForArrow( editor, cursor );
1329
1330 ME_ScrollUp( editor, editor->sizeWindow.cy );
1331 /* Only move the cursor by the amount scrolled. */
1332 yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos;
1333 last_row = row;
1334
1335 while ((row = row_prev_all_paras( row )))
1336 {
1337 if (row_para( row )->pt.y + row->pt.y < yd) break;
1338 last_row = row;
1339 }
1340
1341 row_cursor( editor, last_row, x, cursor );
1342 }
1343}
void ME_ScrollUp(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN
Definition: paint.c:1127

Referenced by ME_ArrowKey().

◆ ME_CharFromPos()

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

Definition at line 1039 of file caret.c.

1041{
1042 RECT rc;
1043 BOOL bResult;
1044
1045 ITextHost_TxGetClientRect(editor->texthost, &rc);
1046 if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom) {
1047 if (isExact) *isExact = FALSE;
1048 return FALSE;
1049 }
1050 x += editor->horz_si.nPos;
1051 y += editor->vert_si.nPos;
1052 bResult = cursor_from_virtual_coords( editor, x, y, cursor, FALSE );
1053 if (isExact) *isExact = bResult;
1054 return TRUE;
1055}
static BOOL cursor_from_virtual_coords(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL final_eop)
Definition: caret.c:978
#define ITextHost_TxGetClientRect(This, a)
Definition: editor.h:354
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309

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

◆ ME_DeleteSelection()

void ME_DeleteSelection ( ME_TextEditor editor)

Definition at line 1406 of file caret.c.

1407{
1408 int from, to;
1409 int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
1410 int nEndCursor = nStartCursor ^ 1;
1411 ME_DeleteTextAtCursor(editor, nStartCursor, to - from);
1412 editor->pCursors[nEndCursor] = editor->pCursors[nStartCursor];
1413}
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
Definition: caret.c:481
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
Definition: caret.c:42
CardRegion * from
Definition: spigame.cpp:19

Referenced by editor_handle_message(), ME_InsertEndRowFromCursor(), ME_InsertOLEFromCursor(), 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 1069 of file caret.c.

1070{
1071 ME_Cursor tmp_cursor;
1072 int curOfs, anchorStartOfs, anchorEndOfs;
1073 if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument)
1074 return;
1075 curOfs = ME_GetCursorOfs(&editor->pCursors[0]);
1076 anchorStartOfs = ME_GetCursorOfs(&editor->pCursors[3]);
1077 anchorEndOfs = ME_GetCursorOfs(&editor->pCursors[2]);
1078
1079 tmp_cursor = editor->pCursors[0];
1080 editor->pCursors[0] = editor->pCursors[2];
1081 editor->pCursors[1] = editor->pCursors[3];
1082 if (curOfs < anchorStartOfs)
1083 {
1084 /* Extend the left side of selection */
1085 editor->pCursors[1] = tmp_cursor;
1086 switch (editor->nSelectionType)
1087 {
1088 case stWord:
1089 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
1090 break;
1091
1092 case stLine:
1093 {
1094 ME_Row *row = row_from_cursor( editor->pCursors + 1 );
1095 row_first_cursor( row, editor->pCursors + 1 );
1096 break;
1097 }
1098
1099 case stParagraph:
1100 editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
1101 editor->pCursors[1].nOffset = 0;
1102 break;
1103
1104 default:
1105 break;
1106 }
1107 }
1108 else if (curOfs >= anchorEndOfs)
1109 {
1110 /* Extend the right side of selection */
1111 editor->pCursors[0] = tmp_cursor;
1112 switch (editor->nSelectionType)
1113 {
1114 case stWord:
1115 ME_MoveCursorWords( editor, &editor->pCursors[0], +1 );
1116 break;
1117
1118 case stLine:
1119 {
1120 ME_Row *row = row_from_cursor( editor->pCursors );
1121 row_end_cursor( row, editor->pCursors, TRUE );
1122 break;
1123 }
1124
1125 case stParagraph:
1126 editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
1127 editor->pCursors[0].para = editor->pCursors[0].run->para;
1128 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
1129 break;
1130
1131 default:
1132 break;
1133 }
1134 }
1135}
int ME_GetCursorOfs(const ME_Cursor *cursor)
Definition: caret.c:889
ME_Run * para_first_run(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:104
ME_Run * para_end_run(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:117
@ stWord
Definition: editstr.h:357
@ stParagraph
Definition: editstr.h:359
@ stPosition
Definition: editstr.h:356
@ stLine
Definition: editstr.h:358
@ stDocument
Definition: editstr.h:360
ME_Paragraph * para
Definition: editstr.h:274
int nOffset
Definition: editstr.h:276
ME_Run * run
Definition: editstr.h:275
struct tagME_Paragraph * para
Definition: editstr.h:160
int len
Definition: editstr.h:162
ME_SelectionType nSelectionType
Definition: editstr.h:434

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 1415 of file caret.c.

1416{
1417 return style_get_insert_style( editor, editor->pCursors );
1418}
ME_Style * style_get_insert_style(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: style.c:476

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:2144
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:583
unsigned int bEmulateVersion10
Definition: editstr.h:385
#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 1229 of file caret.c.

1230{
1231 ME_Run *run = pCursor->run;
1232 int x;
1233
1234 if (editor->nUDArrowX != -1)
1235 x = editor->nUDArrowX;
1236 else
1237 {
1238 x = run->pt.x;
1239 x += ME_PointFromChar( editor, run, pCursor->nOffset, TRUE );
1240 editor->nUDArrowX = x;
1241 }
1242 return x;
1243}
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:649

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

◆ ME_InsertEndRowFromCursor()

void ME_InsertEndRowFromCursor ( ME_TextEditor editor,
int  nCursor 
)

Definition at line 537 of file caret.c.

538{
539 const WCHAR space = ' ';
540 ME_Cursor *cursor = editor->pCursors + nCursor;
542
543 /* FIXME no no no */
544 if (ME_IsSelection(editor))
545 ME_DeleteSelection(editor);
546
547 run_insert( editor, cursor, style, &space, 1, MERF_ENDROW );
548
550}
Arabic default style
Definition: afstyles.h:94
BOOL ME_IsSelection(ME_TextEditor *editor)
Definition: caret.c:1400
void ME_DeleteSelection(ME_TextEditor *editor)
Definition: caret.c:1406
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN
Definition: style.c:462
ME_Run * run_insert(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, const WCHAR *str, int len, int flags) DECLSPEC_HIDDEN
Definition: run.c:375
#define MERF_ENDROW
Definition: editstr.h:123
__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 503 of file caret.c.

504{
505 ME_Run *run, *prev;
506 const WCHAR space = ' ';
507 struct re_object *reobj_prev = NULL;
508 ME_Cursor *cursor = editor->pCursors + nCursor;
510
511 /* FIXME no no no */
512 if (ME_IsSelection(editor))
513 ME_DeleteSelection(editor);
514
515 run = run_insert( editor, cursor, style, &space, 1, MERF_GRAPHICS );
516
517 run->reobj = create_re_object( reo );
518
519 prev = run;
520 while ((prev = run_prev_all_paras( prev )))
521 {
522 if (prev->reobj)
523 {
524 reobj_prev = prev->reobj;
525 break;
526 }
527 }
528 if (reobj_prev)
529 list_add_after(&reobj_prev->entry, &run->reobj->entry);
530 else
531 list_add_head(&editor->reobj_list, &run->reobj->entry);
532
534}
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:490
ME_Run * run_prev_all_paras(ME_Run *run) DECLSPEC_HIDDEN
Definition: run.c:110
#define MERF_GRAPHICS
Definition: editstr.h:104
__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:153
struct re_object * reobj
Definition: editstr.h:167
struct list reobj_list
Definition: editstr.h:450

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 553 of file caret.c.

555{
556 const WCHAR *pos;
557 ME_Cursor *cursor = editor->pCursors + nCursor;
558 int oldLen;
559
560 /* FIXME really HERE ? */
561 if (ME_IsSelection(editor))
562 ME_DeleteSelection(editor);
563
564 oldLen = ME_GetTextLength(editor);
565
566 /* text operations set modified state */
567 editor->nModifyStep = 1;
568
569 assert(style);
570
571 if (len == -1) len = lstrlenW( str );
572
573 /* grow the text limit to fit our text */
574 if (editor->nTextLimit < oldLen + len) editor->nTextLimit = oldLen + len;
575
576 pos = str;
577
578 while (len)
579 {
580 /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
581 while (pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t')
582 pos++;
583
584 if (pos != str) /* handle text */
585 run_insert( editor, cursor, style, str, pos - str, 0 );
586 else if (*pos == '\t') /* handle tabs */
587 {
588 const WCHAR tab = '\t';
589 run_insert( editor, cursor, style, &tab, 1, MERF_TAB );
590 pos++;
591 }
592 else /* handle EOLs */
593 {
594 ME_Run *end_run, *run, *prev;
595 ME_Paragraph *new_para;
596 int eol_len = 0;
597
598 /* Check if new line is allowed for this control */
599 if (!(editor->props & TXTBIT_MULTILINE))
600 break;
601
602 /* Find number of CR and LF in end of paragraph run */
603 if (*pos =='\r')
604 {
605 if (len > 1 && pos[1] == '\n')
606 eol_len = 2;
607 else if (len > 2 && pos[1] == '\r' && pos[2] == '\n')
608 eol_len = 3;
609 else
610 eol_len = 1;
611 }
612 else
613 {
614 assert(*pos == '\n');
615 eol_len = 1;
616 }
617 pos += eol_len;
618
619 if (!editor->bEmulateVersion10 && eol_len == 3)
620 {
621 /* handle special \r\r\n sequence (richedit 2.x and higher only) */
622 const WCHAR space = ' ';
623 run_insert( editor, cursor, style, &space, 1, 0 );
624 }
625 else
626 {
627 const WCHAR cr = '\r', *eol_str = str;
628
629 if (!editor->bEmulateVersion10)
630 {
631 eol_str = &cr;
632 eol_len = 1;
633 }
634
635 if (cursor->nOffset == cursor->run->len)
636 {
637 run = run_next( cursor->run );
638 if (!run) run = cursor->run;
639 }
640 else
641 {
642 if (cursor->nOffset) run_split( editor, cursor );
643 run = cursor->run;
644 }
645
646 new_para = para_split( editor, run, style, eol_str, eol_len, 0 );
647 end_run = para_end_run( para_prev( new_para ) );
648
649 /* Move any cursors that were at the end of the previous run to the beginning of the new para */
650 prev = run_prev( end_run );
651 if (prev)
652 {
653 int i;
654 for (i = 0; i < editor->nCursors; i++)
655 {
656 if (editor->pCursors[i].run == prev &&
657 editor->pCursors[i].nOffset == prev->len)
658 {
659 editor->pCursors[i].para = new_para;
660 editor->pCursors[i].run = run;
661 editor->pCursors[i].nOffset = 0;
662 }
663 }
664 }
665
666 }
667 }
668 len -= pos - str;
669 str = pos;
670 }
671}
#define lstrlenW
Definition: compat.h:750
ME_Run * run_next(ME_Run *run) DECLSPEC_HIDDEN
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) DECLSPEC_HIDDEN
Definition: para.c:540
ME_Run * run_split(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:305
#define MERF_TAB
Definition: editstr.h:106
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;
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}
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
ME_Paragraph * para_join(ME_TextEditor *editor, ME_Paragraph *para, BOOL use_first_fmt) DECLSPEC_HIDDEN
Definition: para.c:683
void table_protect_partial_deletion(ME_TextEditor *editor, ME_Cursor *c, int *num_chars) DECLSPEC_HIDDEN
Definition: table.c:217
void editor_propagate_char_ofs(ME_Paragraph *para, ME_Run *run, int shift) DECLSPEC_HIDDEN
Definition: run.c:147
void cursor_from_char_ofs(ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:240
void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN
Definition: list.c:115
void para_mark_rewrap(ME_TextEditor *editor, ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:26
void editor_set_default_para_fmt(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN
Definition: para.c:960
static ME_DisplayItem * run_get_di(ME_Run *run)
Definition: editor.h:163
void ME_Remove(ME_DisplayItem *diWhere) DECLSPEC_HIDDEN
Definition: list.c:35
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:42
static const char * debugstr_run(const ME_Run *run)
Definition: editor.h:47
#define MERF_ENDPARA
Definition: editstr.h:121
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:203
int nCharOfs
Definition: editstr.h:161
ME_Style * style
Definition: editstr.h:159
int nFlags
Definition: editstr.h:164

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 1137 of file caret.c.

1138{
1139 ME_Cursor tmp_cursor;
1140 BOOL is_selection = FALSE, is_shift;
1141
1142 editor->nUDArrowX = -1;
1143
1144 x += editor->horz_si.nPos;
1145 y += editor->vert_si.nPos;
1146
1147 tmp_cursor = editor->pCursors[0];
1148 is_selection = ME_IsSelection(editor);
1149 is_shift = GetKeyState(VK_SHIFT) < 0;
1150
1151 cursor_from_virtual_coords( editor, x, y, &editor->pCursors[0], FALSE );
1152
1153 if (x >= editor->rcFormat.left || is_shift)
1154 {
1155 if (clickNum > 1)
1156 {
1157 editor->pCursors[1] = editor->pCursors[0];
1158 if (is_shift) {
1159 if (x >= editor->rcFormat.left)
1160 ME_SelectByType(editor, stWord);
1161 else
1163 } else if (clickNum % 2 == 0) {
1164 ME_SelectByType(editor, stWord);
1165 } else {
1167 }
1168 }
1169 else if (!is_shift)
1170 {
1171 editor->nSelectionType = stPosition;
1172 editor->pCursors[1] = editor->pCursors[0];
1173 }
1174 else if (!is_selection)
1175 {
1176 editor->nSelectionType = stPosition;
1177 editor->pCursors[1] = tmp_cursor;
1178 }
1179 else if (editor->nSelectionType != stPosition)
1180 {
1182 }
1183 }
1184 else
1185 {
1186 if (clickNum < 2) {
1187 ME_SelectByType(editor, stLine);
1188 } else if (clickNum % 2 == 0 || is_shift) {
1190 } else {
1191 ME_SelectByType(editor, stDocument);
1192 }
1193 }
1194 ME_InvalidateSelection(editor);
1195 update_caret(editor);
1196 ME_SendSelChange(editor);
1197}
static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
Definition: caret.c:1069
static void ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
Definition: caret.c:841
#define VK_SHIFT
Definition: winuser.h:2205
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 1199 of file caret.c.

1200{
1201 ME_Cursor tmp_cursor;
1202
1203 if (editor->nSelectionType == stDocument)
1204 return;
1205 x += editor->horz_si.nPos;
1206 y += editor->vert_si.nPos;
1207
1208 tmp_cursor = editor->pCursors[0];
1209 /* FIXME: do something with the return value of cursor_from_virtual_coords */
1210 cursor_from_virtual_coords( editor, x, y, &tmp_cursor, TRUE );
1211
1212 ME_InvalidateSelection(editor);
1213 editor->pCursors[0] = tmp_cursor;
1215
1216 if (editor->nSelectionType != stPosition &&
1217 memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor)))
1218 /* The scroll the cursor towards the other end, since it was the one
1219 * extended by ME_ExtendAnchorSelection */
1220 editor_ensure_visible( editor, &editor->pCursors[1] );
1221 else
1222 editor_ensure_visible( editor, &editor->pCursors[0] );
1223
1224 ME_InvalidateSelection(editor);
1225 update_caret(editor);
1226 ME_SendSelChange(editor);
1227}
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 678 of file caret.c.

679{
680 cursor->nOffset += nRelOfs;
681 if (cursor->nOffset < 0)
682 {
683 cursor->nOffset += cursor->run->nCharOfs;
684 if (cursor->nOffset >= 0)
685 {
686 /* new offset in the same paragraph */
687 do {
688 cursor->run = run_prev( cursor->run );
689 } while (cursor->nOffset < cursor->run->nCharOfs);
690 cursor->nOffset -= cursor->run->nCharOfs;
691 return nRelOfs;
692 }
693
694 cursor->nOffset += cursor->para->nCharOfs;
695 if (cursor->nOffset <= 0)
696 {
697 /* moved to the start of the text */
698 nRelOfs -= cursor->nOffset;
700 return nRelOfs;
701 }
702
703 /* new offset in a previous paragraph */
704 do {
705 cursor->para = para_prev( cursor->para );
706 } while (cursor->nOffset < cursor->para->nCharOfs);
707 cursor->nOffset -= cursor->para->nCharOfs;
708
709 cursor->run = para_end_run( cursor->para );
710 while (cursor->nOffset < cursor->run->nCharOfs)
711 cursor->run = run_prev( cursor->run );
712 cursor->nOffset -= cursor->run->nCharOfs;
713 }
714 else if (cursor->nOffset >= cursor->run->len)
715 {
716 ME_Paragraph *next_para;
717 int new_offset;
718
719 new_offset = ME_GetCursorOfs(cursor);
720 next_para = para_next( cursor->para );
721 if (new_offset < next_para->nCharOfs)
722 {
723 /* new offset in the same paragraph */
724 do {
725 cursor->nOffset -= cursor->run->len;
726 cursor->run = run_next( cursor->run );
727 } while (cursor->nOffset >= cursor->run->len);
728 return nRelOfs;
729 }
730
731 if (new_offset >= ME_GetTextLength(editor) + (final_eop ? 1 : 0))
732 {
733 /* new offset at the end of the text */
734 ME_SetCursorToEnd(editor, cursor, final_eop);
735 nRelOfs -= new_offset - (ME_GetTextLength(editor) + (final_eop ? 1 : 0));
736 return nRelOfs;
737 }
738
739 /* new offset in a following paragraph */
740 do {
741 cursor->para = next_para;
742 next_para = para_next( next_para );
743 } while (new_offset >= next_para->nCharOfs);
744
745 cursor->nOffset = new_offset - cursor->para->nCharOfs;
746 cursor->run = para_first_run( cursor->para );
747 while (cursor->nOffset >= cursor->run->len)
748 {
749 cursor->nOffset -= cursor->run->len;
750 cursor->run = run_next( cursor->run );
751 }
752 } /* else new offset is in the same run */
753 return nRelOfs;
754}

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 758 of file caret.c.

759{
760 ME_Run *run = cursor->run, *other_run;
761 ME_Paragraph *para = cursor->para;
762 int nOffset = cursor->nOffset;
763
764 if (nRelOfs == -1)
765 {
766 /* Backward movement */
767 while (TRUE)
768 {
769 nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDLEFT );
770 if (nOffset) break;
771 other_run = run_prev( run );
772 if (other_run)
773 {
774 if (ME_CallWordBreakProc( editor, get_text( other_run, 0 ), other_run->len, other_run->len - 1, WB_ISDELIMITER )
775 && !(run->nFlags & MERF_ENDPARA)
776 && !(cursor->run == run && cursor->nOffset == 0)
777 && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, 0, WB_ISDELIMITER ))
778 break;
779 run = other_run;
780 nOffset = other_run->len;
781 }
782 else
783 {
784 if (cursor->run == run && cursor->nOffset == 0)
785 {
786 para = run->para;
787 /* Skip empty start of table row paragraph */
788 if (para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART)
789 para = para_prev( para );
790 /* Paragraph breaks are treated as separate words */
791 if (!para_prev( para )) return FALSE;
792 para = para_prev( para );
793 run = para_end_run( para );
794 }
795 break;
796 }
797 }
798 }
799 else
800 {
801 /* Forward movement */
802 BOOL last_delim = FALSE;
803
804 while (TRUE)
805 {
806 if (last_delim && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_ISDELIMITER ))
807 break;
808 nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDRIGHT );
809 if (nOffset < run->len) break;
810 other_run = run_next( run );
811 if (other_run)
812 {
813 last_delim = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset - 1, WB_ISDELIMITER );
814 run = other_run;
815 nOffset = 0;
816 }
817 else
818 {
819 para = para_next( para );
820 if (!para_next( para ))
821 {
822 if (cursor->run == run) return FALSE;
823 nOffset = 0;
824 break;
825 }
826 if (para->nFlags & MEPF_ROWSTART) para = para_next( para );
827 if (cursor->run == run) run = para_first_run( para );
828 nOffset = 0;
829 break;
830 }
831 }
832 }
833 cursor->para = para;
834 cursor->run = run;
835 cursor->nOffset = nOffset;
836 return TRUE;
837}
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 841 of file caret.c.

842{
843 /* pCursor[0] is the end of the selection
844 * pCursor[1] is the start of the selection (or the position selection anchor)
845 * pCursor[2] and [3] are the selection anchors that are backed up
846 * so they are kept when the selection changes for drag selection.
847 */
848
849 editor->nSelectionType = selectionType;
850 switch(selectionType)
851 {
852 case stPosition:
853 break;
854 case stWord:
855 ME_MoveCursorWords(editor, &editor->pCursors[0], +1);
856 editor->pCursors[1] = editor->pCursors[0];
857 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
858 break;
859 case stParagraph:
860 editor->pCursors[1] = editor->pCursors[0];
861
862 editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
863 editor->pCursors[0].para = editor->pCursors[0].run->para;
864 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
865
866 editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
867 editor->pCursors[1].nOffset = 0;
868 break;
869 case stLine:
870 {
871 ME_Row *row = row_from_cursor( editor->pCursors );
872
873 row_first_cursor( row, editor->pCursors + 1 );
874 row_end_cursor( row, editor->pCursors, TRUE );
875 break;
876 }
877 case stDocument:
878 /* Select everything with cursor anchored from the start of the text */
879 ME_SetCursorToStart(editor, &editor->pCursors[1]);
880 ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE);
881 break;
882 default: assert(0);
883 }
884 /* Store the anchor positions for extending the selection. */
885 editor->pCursors[2] = editor->pCursors[0];
886 editor->pCursors[3] = editor->pCursors[1];
887}

Referenced by ME_LButtonDown().

◆ ME_SendSelChange()

void ME_SendSelChange ( ME_TextEditor editor)

Definition at line 1420 of file caret.c.

1421{
1422 SELCHANGE sc;
1423
1424 sc.nmhdr.hwndFrom = NULL;
1425 sc.nmhdr.idFrom = 0;
1426 sc.nmhdr.code = EN_SELCHANGE;
1427 ME_GetSelectionOfs(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
1428 sc.seltyp = SEL_EMPTY;
1429 if (sc.chrg.cpMin != sc.chrg.cpMax)
1430 sc.seltyp |= SEL_TEXT;
1431 if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */
1432 sc.seltyp |= SEL_MULTICHAR;
1433
1434 if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax)
1435 {
1436 ME_ClearTempStyle(editor);
1437
1438 editor->notified_cr = sc.chrg;
1439
1440 if (editor->nEventMask & ENM_SELCHANGE)
1441 {
1442 TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n",
1443 sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,
1444 (sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "",
1445 (sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : "");
1446 ITextHost_TxNotify(editor->texthost, sc.nmhdr.code, &sc);
1447 }
1448 }
1449}
#define ITextHost_TxNotify(This, a, b)
Definition: editor.h:368
void ME_ClearTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN
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:437
UINT_PTR idFrom
Definition: winuser.h:3161
UINT code
Definition: winuser.h:3162
HWND hwndFrom
Definition: winuser.h:3160

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 895 of file caret.c.

896{
897 ME_Cell *cell, *next_cell;
898
899 assert( para->nFlags & MEPF_ROWSTART );
900 cell = table_row_first_cell( para );
901 assert( cell );
902
903 /* find the cell we are in */
904 while ((next_cell = cell_next( cell )) != NULL)
905 {
906 if (x < next_cell->pt.x)
907 {
908 para = cell_first_para( cell );
909 /* Found the cell, but there might be multiple paragraphs in
910 * the cell, so need to search down the cell for the paragraph. */
911 while (cell == para_cell( para ))
912 {
913 if (y < para->pt.y + para->nHeight)
914 {
915 if (para->nFlags & MEPF_ROWSTART) return pixel_pos_in_table_row( x, y, para );
916 else return para;
917 }
918 para = para_next( para );
919 }
920 /* Past the end of the cell, so go back to the last cell paragraph */
921 return para_prev( para );
922 }
923 cell = next_cell;
924 }
925 /* Return table row delimiter */
926 para = table_row_end( para );
927 assert( para->nFlags & MEPF_ROWEND );
930 return para;
931}
#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 933 of file caret.c.

935{
936 ME_Run *run, *last;
937 BOOL exact = TRUE;
938
939 if (x < row->pt.x)
940 {
941 x = row->pt.x;
942 exact = FALSE;
943 }
944
945 run = row_first_run( row );
946 assert( run );
947 cursor->nOffset = 0;
948 do
949 {
950 if (x >= run->pt.x && x < run->pt.x + run->nWidth)
951 {
952 cursor->nOffset = ME_CharFromPoint( editor, x - run->pt.x, run, TRUE, TRUE );
953 cursor->run = run;
954 cursor->para = run->para;
955 return exact;
956 }
957 last = run;
958 run = row_next_run( row, run );
959 } while (run);
960
961 run = last;
962
963 cursor->run = run;
964 cursor->para = run->para;
965 return FALSE;
966}
ME_Run * row_next_run(ME_Row *row, ME_Run *run) DECLSPEC_HIDDEN
Definition: row.c:63
ME_Run * row_first_run(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:54
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:570
static UINT UINT last
Definition: font.c:45
int nWidth
Definition: editstr.h:163

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 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 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
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:1045
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1086
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:343
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN
Definition: run.c:853
#define CFS_RECT
Definition: imm.h:324
#define CFS_POINT
Definition: imm.h:325
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
#define ZeroMemory
Definition: winbase.h:1737
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  )