richedit: Use ME_Cursor instead of offsets for copying text.

This commit is contained in:
Dylan Smith 2009-08-13 08:44:05 -04:00 committed by Alexandre Julliard
parent 60a72583f4
commit a69ef26599
4 changed files with 44 additions and 29 deletions

View File

@ -326,26 +326,23 @@ static const IDataObjectVtbl VT_DataObjectImpl =
DataObjectImpl_EnumDAdvise
};
static HGLOBAL get_unicode_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
{
int pars = 0;
int len;
WCHAR *data;
HANDLE ret;
ME_Cursor start;
ME_DisplayItem *para;
int nEnd = ME_GetCursorOfs(start) + nChars;
ME_CursorFromCharOfs(editor, lpchrg->cpMin, &start);
/* count paragraphs in range */
para = start.pPara;
para = start->pPara;
while((para = para->member.para.next_para) &&
para->member.para.nCharOfs <= lpchrg->cpMax)
para->member.para.nCharOfs <= nEnd)
pars++;
len = lpchrg->cpMax-lpchrg->cpMin;
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR)*(len+pars+1));
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1));
data = GlobalLock(ret);
len = ME_GetTextW(editor, data, len+pars, &start, len, TRUE);
ME_GetTextW(editor, data, nChars + pars, start, nChars, TRUE);
GlobalUnlock(ret);
return ret;
}
@ -392,10 +389,11 @@ static HGLOBAL get_rtf_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
return gds.hData;
}
HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAOBJECT *lplpdataobj)
HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
int nChars, LPDATAOBJECT *lplpdataobj)
{
DataObjectImpl *obj;
TRACE("(%p,%d,%d)\n", editor, lpchrg->cpMin, lpchrg->cpMax);
TRACE("(%p,%d,%d)\n", editor, ME_GetCursorOfs(start), nChars);
obj = heap_alloc(sizeof(DataObjectImpl));
if(cfRTF == 0)
@ -403,7 +401,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAO
obj->lpVtbl = &VT_DataObjectImpl;
obj->ref = 1;
obj->unicode = get_unicode_text(editor, lpchrg);
obj->unicode = get_unicode_text(editor, start, nChars);
obj->rtf = NULL;
obj->fmtetc_cnt = 1;
@ -412,7 +410,10 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAO
obj->fmtetc = GlobalAlloc(GMEM_ZEROINIT, obj->fmtetc_cnt*sizeof(FORMATETC));
InitFormatEtc(obj->fmtetc[0], CF_UNICODETEXT, TYMED_HGLOBAL);
if(editor->mode & TM_RICHTEXT) {
obj->rtf = get_rtf_text(editor, lpchrg);
CHARRANGE chrg;
chrg.cpMin = ME_GetCursorOfs(start);
chrg.cpMax = chrg.cpMin + nChars;
obj->rtf = get_rtf_text(editor, &chrg);
InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL);
}

View File

@ -2001,7 +2001,7 @@ static BOOL ME_Paste(ME_TextEditor *editor)
return TRUE;
}
static BOOL ME_Copy(ME_TextEditor *editor, CHARRANGE *range)
static BOOL ME_Copy(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
{
LPDATAOBJECT dataObj = NULL;
HRESULT hr = S_OK;
@ -2010,9 +2010,14 @@ static BOOL ME_Copy(ME_TextEditor *editor, CHARRANGE *range)
return FALSE; /* Copying or Cutting masked text isn't allowed */
if(editor->lpOleCallback)
hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, range, RECO_COPY, &dataObj);
{
CHARRANGE range;
range.cpMin = ME_GetCursorOfs(start);
range.cpMax = range.cpMin + nChars;
hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj);
}
if(FAILED(hr) || !dataObj)
hr = ME_GetDataObject(editor, range, &dataObj);
hr = ME_GetDataObject(editor, start, nChars, &dataObj);
if(SUCCEEDED(hr)) {
hr = OleSetClipboard(dataObj);
IDataObject_Release(dataObj);
@ -2270,14 +2275,16 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
case 'X':
if (ctrl_is_down)
{
CHARRANGE range;
BOOL result;
int nOfs, nChars;
int nStartCur = ME_GetSelectionOfs(editor, &nOfs, &nChars);
ME_Cursor *selStart = &editor->pCursors[nStartCur];
ME_GetSelectionOfs(editor, &range.cpMin, &range.cpMax);
result = ME_Copy(editor, &range);
nChars -= nOfs;
result = ME_Copy(editor, selStart, nChars);
if (result && nKey == 'X')
{
ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE);
ME_InternalDeleteText(editor, nOfs, nChars, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor);
}
@ -3537,12 +3544,14 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case WM_CUT:
case WM_COPY:
{
CHARRANGE range;
ME_GetSelectionOfs(editor, &range.cpMin, &range.cpMax);
int nOfs, nChars;
int nStartCur = ME_GetSelectionOfs(editor, &nOfs, &nChars);
ME_Cursor *selStart = &editor->pCursors[nStartCur];
if (ME_Copy(editor, &range) && msg == WM_CUT)
nChars -= nOfs;
if (ME_Copy(editor, selStart, nChars) && msg == WM_CUT)
{
ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE);
ME_InternalDeleteText(editor, nOfs, nChars, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor);
}

View File

@ -335,4 +335,4 @@ LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream);
/* clipboard.c */
HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAOBJECT *lplpdataobj);
HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start, int nChars, LPDATAOBJECT *lplpdataobj);

View File

@ -315,16 +315,21 @@ IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
DWORD reco, LPDATAOBJECT *lplpdataobj)
{
IRichEditOleImpl *This = impl_from_IRichEditOle(me);
CHARRANGE tmpchrg;
ME_Cursor start;
int nChars;
TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
if(!lplpdataobj)
return E_INVALIDARG;
if(!lpchrg) {
ME_GetSelectionOfs(This->editor, &tmpchrg.cpMin, &tmpchrg.cpMax);
lpchrg = &tmpchrg;
int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
start = This->editor->pCursors[nStartCur];
nChars = nTo - nFrom;
} else {
ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
nChars = lpchrg->cpMax - lpchrg->cpMin;
}
return ME_GetDataObject(This->editor, lpchrg, lplpdataobj);
return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
}
static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)