Dylan Smith : richedit: Modified ME_MoveCursorsChars to move multiple chars .
Alexandre Julliard
julliard at winehq.org
Thu Aug 13 10:40:51 CDT 2009
Module: wine
Branch: master
Commit: 27c28ab2928c97b925264f5e0d028426208ac245
URL: http://source.winehq.org/git/wine.git/?a=commit;h=27c28ab2928c97b925264f5e0d028426208ac245
Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date: Thu Aug 13 08:43:57 2009 -0400
richedit: Modified ME_MoveCursorsChars to move multiple chars.
Previously the function was only used to move a single character in
either direction, so I made the function more general so that it could
be used in more places.
---
dlls/riched20/caret.c | 132 +++++++++++++++++++++++++-----------------------
dlls/riched20/editor.h | 1 +
dlls/riched20/undo.c | 3 +-
3 files changed, 72 insertions(+), 64 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 328109d..0cece5e 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -24,9 +24,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
-static BOOL
-ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs);
-
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
{
cursor->pPara = editor->pBuffer->pFirst->member.para.next_para;
@@ -183,7 +180,8 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
}
ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]);
- ME_CursorFromCharOfs(editor, to, &editor->pCursors[0]);
+ editor->pCursors[0] = editor->pCursors[1];
+ ME_MoveCursorChars(editor, &editor->pCursors[0], to - from);
/* Selection is not allowed in the middle of an end paragraph run. */
if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA)
editor->pCursors[1].nOffset = 0;
@@ -601,77 +599,85 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
}
}
-
-static BOOL
-ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
+/* Move the cursor nRelOfs characters (either forwards or backwards)
+ *
+ * returns the actual number of characters moved.
+ **/
+int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
- ME_DisplayItem *pRun = pCursor->pRun;
-
- if (nRelOfs == -1)
+ cursor->nOffset += nRelOfs;
+ if (cursor->nOffset < 0)
{
- if (!pCursor->nOffset)
+ cursor->nOffset += cursor->pRun->member.run.nCharOfs;
+ if (cursor->nOffset >= 0)
{
- ME_DisplayItem *pPara = pCursor->pPara;
+ /* new offset in the same paragraph */
do {
- pRun = ME_FindItemBack(pRun, diRunOrParagraph);
- assert(pRun);
- switch (pRun->type)
- {
- case diRun:
- break;
- case diParagraph:
- pPara = pRun;
- if (pPara->member.para.prev_para->type == diTextStart)
- return FALSE;
- pRun = ME_FindItemBack(pPara, diRunOrParagraph);
- pPara = pPara->member.para.prev_para;
- /* every paragraph ought to have at least one run */
- assert(pRun && pRun->type == diRun);
- assert(pRun->member.run.nFlags & MERF_ENDPARA);
- break;
- default:
- assert(pRun->type != diRun && pRun->type != diParagraph);
- return FALSE;
- }
- } while (RUN_IS_HIDDEN(&pRun->member.run) ||
- pRun->member.run.nFlags & MERF_HIDDEN);
- pCursor->pPara = pPara;
- pCursor->pRun = pRun;
- if (pRun->member.run.nFlags & MERF_ENDPARA)
- pCursor->nOffset = 0;
- else
- pCursor->nOffset = pRun->member.run.strText->nLen;
+ cursor->pRun = ME_FindItemBack(cursor->pRun, diRun);
+ } while (cursor->nOffset < cursor->pRun->member.run.nCharOfs);
+ cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
+ return nRelOfs;
}
- if (pCursor->nOffset)
- pCursor->nOffset = pCursor->nOffset + nRelOfs;
- return TRUE;
- }
- else
- {
- if (!(pRun->member.run.nFlags & MERF_ENDPARA))
+ cursor->nOffset += cursor->pPara->member.para.nCharOfs;
+ if (cursor->nOffset <= 0)
{
- int new_ofs = pCursor->nOffset + nRelOfs;
+ /* moved to the start of the text */
+ nRelOfs -= cursor->nOffset;
+ ME_SetCursorToStart(editor, cursor);
+ return nRelOfs;
+ }
- if (new_ofs < pRun->member.run.strText->nLen)
- {
- pCursor->nOffset = new_ofs;
- return TRUE;
- }
+ /* new offset in a previous paragraph */
+ do {
+ cursor->pPara = cursor->pPara->member.para.prev_para;
+ } while (cursor->nOffset < cursor->pPara->member.para.nCharOfs);
+ cursor->nOffset -= cursor->pPara->member.para.nCharOfs;
+
+ cursor->pRun = ME_FindItemBack(cursor->pPara->member.para.next_para, diRun);
+ while (cursor->nOffset < cursor->pRun->member.run.nCharOfs) {
+ cursor->pRun = ME_FindItemBack(cursor->pRun, diRun);
}
+ cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
+ } else if (cursor->nOffset >= cursor->pRun->member.run.strText->nLen) {
+ ME_DisplayItem *next_para;
+ int new_offset;
+
+ new_offset = ME_GetCursorOfs(cursor);
+ next_para = cursor->pPara->member.para.next_para;
+ if (new_offset < next_para->member.para.nCharOfs)
+ {
+ /* new offset in the same paragraph */
+ do {
+ cursor->nOffset -= cursor->pRun->member.run.strText->nLen;
+ cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun);
+ } while (cursor->nOffset >= cursor->pRun->member.run.strText->nLen);
+ return nRelOfs;
+ }
+
+ if (new_offset >= ME_GetTextLength(editor))
+ {
+ /* new offset at the end of the text */
+ ME_SetCursorToEnd(editor, cursor);
+ nRelOfs -= new_offset - ME_GetTextLength(editor);
+ return nRelOfs;
+ }
+
+ /* new offset in a following paragraph */
do {
- pRun = ME_FindItemFwd(pRun, diRun);
- } while (pRun && (RUN_IS_HIDDEN(&pRun->member.run) ||
- pRun->member.run.nFlags & MERF_HIDDEN));
- if (pRun)
+ cursor->pPara = next_para;
+ next_para = next_para->member.para.next_para;
+ } while (new_offset >= next_para->member.para.nCharOfs);
+
+ cursor->nOffset = new_offset - cursor->pPara->member.para.nCharOfs;
+ cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun);
+ while (cursor->nOffset >= cursor->pRun->member.run.strText->nLen)
{
- pCursor->pPara = ME_GetParagraph(pRun);
- pCursor->pRun = pRun;
- pCursor->nOffset = 0;
- return TRUE;
+ cursor->nOffset -= cursor->pRun->member.run.strText->nLen;
+ cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun);
}
- }
- return FALSE;
+ } /* else new offset is in the same run */
+ return nRelOfs;
}
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 07fabdb..14750c8 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -169,6 +169,7 @@ BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style);
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor);
+int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl);
int ME_GetCursorOfs(const ME_Cursor *cursor);
diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c
index 84285b8..908a5ac 100644
--- a/dlls/riched20/undo.c
+++ b/dlls/riched20/undo.c
@@ -300,7 +300,8 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
{
ME_Cursor start, end;
ME_CursorFromCharOfs(editor, pUItem->nStart, &start);
- ME_CursorFromCharOfs(editor, pUItem->nStart + pUItem->nLen, &end);
+ end = start;
+ ME_MoveCursorChars(editor, &end, pUItem->nLen);
ME_SetCharFormat(editor, &start, &end, &pItem->member.ustyle->fmt);
break;
}
More information about the wine-cvs
mailing list