void ME_LButtonDown(ME_TextEditor *editor, int x, int y) { ME_Cursor tmp_cursor; int is_selection = 0; editor->nUDArrowX = -1; y += ME_GetYScrollPos(editor); tmp_cursor = editor->pCursors[0]; is_selection = ME_IsSelection(editor); ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); if (GetKeyState(VK_SHIFT)>=0) { editor->pCursors[1] = editor->pCursors[0]; } else { if (!is_selection) { editor->pCursors[1] = tmp_cursor; is_selection = 1; } } ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_MoveCaret(editor); ShowCaret(editor->hWnd); ME_ClearTempStyle(editor); ME_SendSelChange(editor); }
void ME_HideCaret(ME_TextEditor *ed) { if(!ed->bHaveFocus || ME_IsSelection(ed)) { ITextHost_TxShowCaret(ed->texthost, FALSE); DestroyCaret(); } }
void ME_HideCaret(ME_TextEditor *ed) { if(!ed->bHaveFocus || ME_IsSelection(ed)) { HideCaret(ed->hWnd); DestroyCaret(); } }
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) { /* FIXME: Shift tab should move to the previous cell. */ ME_Cursor fromCursor, toCursor; ME_InvalidateSelection(editor); { int from, to; from = ME_GetCursorOfs(editor, 0); to = ME_GetCursorOfs(editor, 1); if (from <= to) { fromCursor = editor->pCursors[0]; toCursor = editor->pCursors[1]; } else { fromCursor = editor->pCursors[1]; toCursor = editor->pCursors[0]; } } if (!editor->bEmulateVersion10) /* v4.1 */ { if (!ME_IsInTable(toCursor.pRun)) { editor->pCursors[0] = toCursor; editor->pCursors[1] = toCursor; } else { ME_SelectOrInsertNextCell(editor, toCursor.pRun); } } else { /* v1.0 - 3.0 */ if (!ME_IsInTable(fromCursor.pRun)) { editor->pCursors[0] = fromCursor; editor->pCursors[1] = fromCursor; /* FIXME: For some reason the caret is shown at the start of the * previous paragraph in v1.0 to v3.0, and bCaretAtEnd only works * within the paragraph for wrapped lines. */ if (ME_FindItemBack(fromCursor.pRun, diRun)) editor->bCaretAtEnd = TRUE; } else if ((bSelectedRow || !ME_IsInTable(toCursor.pRun))) { ME_SelectOrInsertNextCell(editor, fromCursor.pRun); } else { if (ME_IsSelection(editor) && !toCursor.nOffset) { ME_DisplayItem *run; run = ME_FindItemBack(toCursor.pRun, diRunOrParagraphOrEnd); if (run->type == diRun && run->member.run.nFlags & MERF_TAB) ME_SelectOrInsertNextCell(editor, run); else ME_SelectOrInsertNextCell(editor, toCursor.pRun); } else { ME_SelectOrInsertNextCell(editor, toCursor.pRun); } } } ME_InvalidateSelection(editor); ME_Repaint(editor); HideCaret(editor->hWnd); ME_ShowCaret(editor); ME_SendSelChange(editor); }
/* FIXME this is temporary, just to have something to test how bad graphics handler is */ void ME_InsertGraphicsFromCursor(ME_TextEditor *editor, int nCursor) { ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); WCHAR space = ' '; /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, MERF_GRAPHICS); ME_SendSelChange(editor); }
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor) { ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); WCHAR space = ' '; /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, MERF_ENDROW); ME_ReleaseStyle(pStyle); }
void ME_MoveCaret(ME_TextEditor *editor) { int x, y, height; ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); if(editor->bHaveFocus && !ME_IsSelection(editor)) { x = min(x, editor->rcFormat.right-1); ITextHost_TxCreateCaret(editor->texthost, NULL, 0, height); ITextHost_TxSetCaretPos(editor->texthost, x, y); } }
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor) { ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); ME_DisplayItem *di; WCHAR space = ' '; /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, MERF_ENDROW); ME_SendSelChange(editor); }
void ME_MoveCaret(ME_TextEditor *editor) { int x, y, height; if (ME_WrapMarkedParagraphs(editor)) ME_UpdateScrollBar(editor); ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); if(editor->bHaveFocus && !ME_IsSelection(editor)) { x = min(x, editor->rcFormat.right-1); CreateCaret(editor->hWnd, NULL, 0, height); SetCaretPos(x, y); } }
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor) { ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); ME_DisplayItem *di; WCHAR space = ' '; /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, MERF_GRAPHICS); di->member.run.ole_obj = ALLOC_OBJ(*reo); ME_CopyReObject(di->member.run.ole_obj, reo); ME_SendSelChange(editor); }
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) { if (ME_IsSelection(editor)) { ME_Cursor c; int from, to; ME_GetSelection(editor, &from, &to); ME_CursorFromCharOfs(editor, from, &c); ME_AddRefStyle(c.pRun->member.run.style); return c.pRun->member.run.style; } if (editor->pBuffer->pCharStyle) { ME_AddRefStyle(editor->pBuffer->pCharStyle); return editor->pBuffer->pCharStyle; } else { ME_Cursor *pCursor = &editor->pCursors[nCursor]; ME_DisplayItem *pRunItem = pCursor->pRun; ME_DisplayItem *pPrevItem = NULL; if (pCursor->nOffset) { ME_Run *pRun = &pRunItem->member.run; ME_AddRefStyle(pRun->style); return pRun->style; } pPrevItem = ME_FindItemBack(pRunItem, diRunOrParagraph); if (pPrevItem->type == diRun) { ME_AddRefStyle(pPrevItem->member.run.style); return pPrevItem->member.run.style; } else { ME_AddRefStyle(pRunItem->member.run.style); return pRunItem->member.run.style; } } }
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style) { const WCHAR *pos; ME_Cursor *p = NULL; int oldLen; /* FIXME really HERE ? */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); /* FIXME: is this too slow? */ /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */ oldLen = ME_GetTextLength(editor); /* text operations set modified state */ editor->nModifyStep = 1; assert(style); assert(nCursor>=0 && nCursor<editor->nCursors); if (len == -1) len = lstrlenW(str); /* grow the text limit to fit our text */ if(editor->nTextLimit < oldLen +len) editor->nTextLimit = oldLen + len; while (len) { pos = str; /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */ while(pos-str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') pos++; if (pos-str < len && *pos == '\t') { /* handle tabs */ WCHAR tab = '\t'; if (pos!=str) ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB); pos++; if(pos-str <= len) { len -= pos - str; str = pos; continue; } } /* handle special \r\r\n sequence (richedit 2.x and higher only) */ if (!editor->bEmulateVersion10 && pos-str < len-2 && pos[0] == '\r' && pos[1] == '\r' && pos[2] == '\n') { WCHAR space = ' '; if (pos!=str) ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0); pos+=3; if(pos-str <= len) { len -= pos - str; str = pos; continue; } } if (pos-str < len) { /* handle EOLs */ ME_DisplayItem *tp, *end_run; ME_Style *tmp_style; int numCR, numLF; if (pos!=str) ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); p = &editor->pCursors[nCursor]; if (p->nOffset) { ME_SplitRunSimple(editor, p->pRun, p->nOffset); p = &editor->pCursors[nCursor]; } tmp_style = ME_GetInsertStyle(editor, nCursor); /* ME_SplitParagraph increases style refcount */ /* Encode and fill number of CR and LF according to emulation mode */ if (editor->bEmulateVersion10) { const WCHAR * tpos; /* We have to find out how many consecutive \r are there, and if there is a \n terminating the run of \r's. */ numCR = 0; numLF = 0; tpos = pos; while (tpos-str < len && *tpos == '\r') { tpos++; numCR++; } if (tpos-str >= len) { /* Reached end of text without finding anything but '\r' */ if (tpos != pos) { pos++; } numCR = 1; numLF = 0; } else if (*tpos == '\n') { /* The entire run of \r's plus the one \n is one single line break */ pos = tpos + 1; numLF = 1; } else { /* Found some other content past the run of \r's */ pos++; numCR = 1; numLF = 0; } } else { if(pos-str < len && *pos =='\r') pos++; if(pos-str < len && *pos =='\n') pos++; numCR = 1; numLF = 0; } tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, numCR, numLF, 0); p->pRun = ME_FindItemFwd(tp, diRun); end_run = ME_FindItemBack(tp, diRun); ME_ReleaseStyle(end_run->member.run.style); end_run->member.run.style = tmp_style; p->nOffset = 0; if(pos-str <= len) { len -= pos - str; str = pos; continue; } } ME_InternalInsertTextFromCursor(editor, nCursor, str, len, style, 0); len = 0; } }
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style) { const WCHAR *pos; ME_Cursor *p = NULL; int oldLen; /* FIXME really HERE ? */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); /* FIXME: is this too slow? */ /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */ oldLen = ME_GetTextLength(editor); /* text operations set modified state */ editor->nModifyStep = 1; assert(style); assert(nCursor>=0 && nCursor<editor->nCursors); if (len == -1) len = lstrlenW(str); /* grow the text limit to fit our text */ if(editor->nTextLimit < oldLen +len) editor->nTextLimit = oldLen + len; pos = str; while (len) { /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */ while(pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') pos++; if (pos != str) { /* handle text */ ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); } else if (*pos == '\t') { /* handle tabs */ WCHAR tab = '\t'; ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB); pos++; } else { /* handle EOLs */ ME_DisplayItem *tp, *end_run, *run, *prev; ME_Style *tmp_style; int eol_len = 0; /* Find number of CR and LF in end of paragraph run */ if (*pos =='\r') { if (len > 1 && pos[1] == '\n') eol_len = 2; else if (len > 2 && pos[1] == '\r' && pos[2] == '\n') eol_len = 3; else eol_len = 1; } else { assert(*pos == '\n'); eol_len = 1; } pos += eol_len; if (!editor->bEmulateVersion10 && eol_len == 3) { /* handle special \r\r\n sequence (richedit 2.x and higher only) */ WCHAR space = ' '; ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0); } else { const WCHAR cr = '\r', *eol_str = str; if (!editor->bEmulateVersion10) { eol_str = &cr; eol_len = 1; } p = &editor->pCursors[nCursor]; if (p->nOffset == p->pRun->member.run.len) { run = ME_FindItemFwd( p->pRun, diRun ); if (!run) run = p->pRun; } else { if (p->nOffset) ME_SplitRunSimple(editor, p); run = p->pRun; } tmp_style = ME_GetInsertStyle(editor, nCursor); /* ME_SplitParagraph increases style refcount */ tp = ME_SplitParagraph(editor, run, run->member.run.style, eol_str, eol_len, 0); end_run = ME_FindItemBack(tp, diRun); ME_ReleaseStyle(end_run->member.run.style); end_run->member.run.style = tmp_style; /* Move any cursors that were at the end of the previous run to the beginning of the new para */ prev = ME_FindItemBack( end_run, diRun ); if (prev) { int i; for (i = 0; i < editor->nCursors; i++) { if (editor->pCursors[i].pRun == prev && editor->pCursors[i].nOffset == prev->member.run.len) { editor->pCursors[i].pPara = tp; editor->pCursors[i].pRun = run; editor->pCursors[i].nOffset = 0; } } } } } len -= pos - str; str = pos; } }
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style) { const WCHAR *pos; ME_Cursor *p = NULL; /* FIXME: is this too slow? */ /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */ int freeSpace = editor->nTextLimit - ME_GetTextLength(editor); /* text operations set modified state */ editor->nModifyStep = 1; assert(style); /* FIXME really HERE ? */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); assert(nCursor>=0 && nCursor<editor->nCursors); if (len == -1) len = lstrlenW(str); len = min(len, freeSpace); while (len) { pos = str; /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */ while(pos-str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') pos++; if (pos-str < len && *pos == '\t') { /* handle tabs */ WCHAR tab = '\t'; if (pos!=str) ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB); pos++; if(pos-str <= len) { len -= pos - str; str = pos; continue; } } if (pos-str < len) { /* handle EOLs */ ME_DisplayItem *tp, *end_run; ME_Style *tmp_style; if (pos!=str) ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); p = &editor->pCursors[nCursor]; if (p->nOffset) { ME_SplitRunSimple(editor, p->pRun, p->nOffset); p = &editor->pCursors[nCursor]; } tmp_style = ME_GetInsertStyle(editor, nCursor); /* ME_SplitParagraph increases style refcount */ tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style); p->pRun = ME_FindItemFwd(tp, diRun); end_run = ME_FindItemBack(tp, diRun); ME_ReleaseStyle(end_run->member.run.style); end_run->member.run.style = tmp_style; p->nOffset = 0; if(pos-str < len && *pos =='\r') pos++; if(pos-str < len && *pos =='\n') pos++; if(pos-str <= len) { len -= pos - str; str = pos; continue; } } ME_InternalInsertTextFromCursor(editor, nCursor, str, len, style, 0); len = 0; } }
void ME_LButtonDown(ME_TextEditor *editor, int x, int y) { ME_Cursor tmp_cursor; int is_selection = 0; editor->nUDArrowX = -1; y += ME_GetYScrollPos(editor); tmp_cursor = editor->pCursors[0]; is_selection = ME_IsSelection(editor); if (x >= editor->selofs) { ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); if (GetKeyState(VK_SHIFT)>=0) { editor->pCursors[1] = editor->pCursors[0]; } else if (!is_selection) { editor->pCursors[1] = tmp_cursor; is_selection = 1; } ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_MoveCaret(editor); ShowCaret(editor->hWnd); ME_ClearTempStyle(editor); ME_SendSelChange(editor); } else { ME_DisplayItem *pRow; editor->linesel = 1; editor->sely = y; /* Set pCursors[0] to beginning of line */ ME_FindPixelPos(editor, x, y, &editor->pCursors[1], &editor->bCaretAtEnd); /* Set pCursors[1] to end of line */ pRow = ME_FindItemFwd(editor->pCursors[1].pRun, diStartRowOrParagraphOrEnd); assert(pRow); /* pCursor[0] is the position where the cursor will be drawn, * pCursor[1] is the other end of the selection range * pCursor[2] and [3] are backups of [0] and [1] so I * don't have to look them up again */ if (pRow->type == diStartRow) { /* FIXME WTF was I thinking about here ? */ ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun); assert(pRun); editor->pCursors[0].pRun = pRun; editor->pCursors[0].nOffset = 0; editor->bCaretAtEnd = 1; } else { editor->pCursors[0].pRun = ME_FindItemBack(pRow, diRun); assert(editor->pCursors[0].pRun && editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA); editor->pCursors[0].nOffset = 0; editor->bCaretAtEnd = 0; } editor->pCursors[2] = editor->pCursors[0]; editor->pCursors[3] = editor->pCursors[1]; ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_MoveCaret(editor); ShowCaret(editor->hWnd); ME_ClearTempStyle(editor); ME_SendSelChange(editor); } }
void ME_ShowCaret(ME_TextEditor *ed) { ME_MoveCaret(ed); if(ed->bHaveFocus && !ME_IsSelection(ed)) ITextHost_TxShowCaret(ed->texthost, TRUE); }
void ME_ShowCaret(ME_TextEditor *ed) { ME_MoveCaret(ed); if(ed->bHaveFocus && !ME_IsSelection(ed)) ShowCaret(ed->hWnd); }
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) { ME_Cursor tmp_cursor; int is_selection = 0; BOOL is_shift; editor->nUDArrowX = -1; x += editor->horz_si.nPos; y += editor->vert_si.nPos; tmp_cursor = editor->pCursors[0]; is_selection = ME_IsSelection(editor); is_shift = GetKeyState(VK_SHIFT) < 0; ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); if (x >= editor->rcFormat.left || is_shift) { if (clickNum > 1) { editor->pCursors[1] = editor->pCursors[0]; if (is_shift) { if (x >= editor->rcFormat.left) ME_SelectByType(editor, stWord); else ME_SelectByType(editor, stParagraph); } else if (clickNum % 2 == 0) { ME_SelectByType(editor, stWord); } else { ME_SelectByType(editor, stParagraph); } } else if (!is_shift) { editor->nSelectionType = stPosition; editor->pCursors[1] = editor->pCursors[0]; } else if (!is_selection) { editor->nSelectionType = stPosition; editor->pCursors[1] = tmp_cursor; } else if (editor->nSelectionType != stPosition) { ME_ExtendAnchorSelection(editor); } } else { if (clickNum < 2) { ME_SelectByType(editor, stLine); } else if (clickNum % 2 == 0 || is_shift) { ME_SelectByType(editor, stParagraph); } else { ME_SelectByType(editor, stDocument); } } ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_ShowCaret(editor); ME_ClearTempStyle(editor); ME_SendSelChange(editor); }