[RICHED20] Sync with Wine Staging 3.9. CORE-14656

This commit is contained in:
Amine Khaldi 2018-06-04 03:48:07 +01:00
parent be43e1385f
commit aefc6e4447
9 changed files with 244 additions and 55 deletions

View file

@ -471,12 +471,26 @@ ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor,
return ME_InsertRunAtCursor(editor, p, style, str, len, flags);
}
static struct re_object* create_re_object(const REOBJECT *reo)
{
struct re_object *reobj = heap_alloc(sizeof(*reobj));
if (!reobj)
{
WARN("Fail to allocate re_object.\n");
return NULL;
}
ME_CopyReObject(&reobj->obj, reo, REO_GETOBJ_ALL_INTERFACES);
return reobj;
}
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor)
{
ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
ME_DisplayItem *di;
WCHAR space = ' ';
ME_DisplayItem *di_prev = NULL;
struct re_object *reobj_prev = NULL;
/* FIXME no no no */
if (ME_IsSelection(editor))
@ -484,8 +498,22 @@ void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCur
di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
MERF_GRAPHICS);
di->member.run.ole_obj = heap_alloc(sizeof(*reo));
ME_CopyReObject(di->member.run.ole_obj, reo);
di->member.run.reobj = create_re_object(reo);
di_prev = di;
while (ME_PrevRun(NULL, &di_prev, TRUE))
{
if (di_prev->member.run.reobj)
{
reobj_prev = di_prev->member.run.reobj;
break;
}
}
if (reobj_prev)
list_add_after(&reobj_prev->entry, &di->member.run.reobj->entry);
else
list_add_head(&editor->reobj_list, &di->member.run.reobj->entry);
ME_ReleaseStyle(pStyle);
}

View file

@ -90,7 +90,7 @@
+ EM_REPLACESEL (proper style?) ANSI&Unicode
+ EM_SCROLL
+ EM_SCROLLCARET
- EM_SELECTIONTYPE
+ EM_SELECTIONTYPE
- EM_SETBIDIOPTIONS 3.0
+ EM_SETBKGNDCOLOR
+ EM_SETCHARFORMAT (partly done, no ANSI)
@ -2964,23 +2964,57 @@ static void ME_SetDefaultFormatRect(ME_TextEditor *editor)
editor->rcFormat.right -= 1;
}
static LONG ME_GetSelectionType(ME_TextEditor *editor)
{
LONG sel_type = SEL_EMPTY;
LONG start, end;
ME_GetSelectionOfs(editor, &start, &end);
if (start == end)
sel_type = SEL_EMPTY;
else
{
LONG object_count = 0, character_count = 0;
int i;
for (i = 0; i < end - start; i++)
{
ME_Cursor cursor;
ME_CursorFromCharOfs(editor, start + i, &cursor);
if (cursor.pRun->member.run.reobj)
object_count++;
else
character_count++;
if (character_count >= 2 && object_count >= 2)
return (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT);
}
if (character_count)
{
sel_type |= SEL_TEXT;
if (character_count >= 2)
sel_type |= SEL_MULTICHAR;
}
if (object_count)
{
sel_type |= SEL_OBJECT;
if (object_count >= 2)
sel_type |= SEL_MULTIOBJECT;
}
}
return sel_type;
}
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
{
CHARRANGE selrange;
HMENU menu;
int seltype = 0;
int seltype;
if(!editor->lpOleCallback || !editor->hWnd)
return FALSE;
ME_GetSelectionOfs(editor, &selrange.cpMin, &selrange.cpMax);
if(selrange.cpMin == selrange.cpMax)
seltype |= SEL_EMPTY;
else
{
/* FIXME: Handle objects */
seltype |= SEL_TEXT;
if(selrange.cpMax-selrange.cpMin > 1)
seltype |= SEL_MULTICHAR;
}
seltype = ME_GetSelectionType(editor);
if(SUCCEEDED(IRichEditOleCallback_GetContextMenu(editor->lpOleCallback, seltype, NULL, &selrange, &menu)))
{
TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, editor->hwndParent, NULL);
@ -3117,6 +3151,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->wheel_remain = 0;
list_init( &ed->style_list );
list_init( &ed->reobj_list );
OleInitialize(NULL);
return ed;
@ -3501,7 +3536,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
UNSUPPORTED_MSG(EM_GETUNDONAME)
UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX)
UNSUPPORTED_MSG(EM_SELECTIONTYPE)
UNSUPPORTED_MSG(EM_SETBIDIOPTIONS)
UNSUPPORTED_MSG(EM_SETEDITSTYLE)
UNSUPPORTED_MSG(EM_SETLANGOPTIONS)
@ -3817,6 +3851,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_UpdateRepaint(editor, FALSE);
return len;
}
case EM_SELECTIONTYPE:
return ME_GetSelectionType(editor);
case EM_SETBKGNDCOLOR:
{
LRESULT lColor;

View file

@ -233,8 +233,8 @@ int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN;
LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN;
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, BOOL selected) DECLSPEC_HIDDEN;
void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN;
void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) DECLSPEC_HIDDEN;
void ME_DeleteReObject(REOBJECT* reo) DECLSPEC_HIDDEN;
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN;
void ME_DeleteReObject(struct re_object *re_object) DECLSPEC_HIDDEN;
void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) DECLSPEC_HIDDEN;
/* editor.c */

View file

@ -153,6 +153,12 @@ typedef enum {
struct tagME_DisplayItem;
struct re_object
{
struct list entry;
REOBJECT obj;
};
typedef struct tagME_Run
{
ME_Style *style;
@ -163,7 +169,7 @@ typedef struct tagME_Run
int nFlags;
int nAscent, nDescent; /* pixels above/below baseline */
POINT pt; /* relative to para's position */
REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */
struct re_object *reobj; /* FIXME: should be a union with strText (at least) */
SCRIPT_ANALYSIS script_analysis;
int num_glyphs, max_glyphs;
@ -436,6 +442,7 @@ typedef struct tagME_TextEditor
BOOL bMouseCaptured;
int wheel_remain;
struct list style_list;
struct list reobj_list;
} ME_TextEditor;
typedef struct tagME_Context

View file

@ -97,7 +97,7 @@ BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para)
{
if (p->type == diParagraph) {
if (!all_para) return FALSE;
if (p->member.para.prev_para->type == diParagraph)
if (para && p->member.para.prev_para->type == diParagraph)
*para = p->member.para.prev_para;
} else if (p->type == diRun) {
*run = p;
@ -169,7 +169,11 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item)
if (item->type==diRun)
{
if (item->member.run.ole_obj) ME_DeleteReObject(item->member.run.ole_obj);
if (item->member.run.reobj)
{
list_remove(&item->member.run.reobj->entry);
ME_DeleteReObject(item->member.run.reobj);
}
heap_free( item->member.run.glyphs );
heap_free( item->member.run.clusters );
ME_ReleaseStyle(item->member.run.style);

View file

@ -1379,16 +1379,46 @@ IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
REOBJECT *lpreobject, DWORD dwFlags)
{
IRichEditOleImpl *This = impl_from_IRichEditOle(me);
FIXME("stub %p\n",This);
return E_NOTIMPL;
struct re_object *reobj = NULL;
LONG count = 0;
TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
if (!lpreobject || !lpreobject->cbStruct)
return E_INVALIDARG;
if (iob == REO_IOB_USE_CP)
{
ME_Cursor cursor;
TRACE("character offset: %d\n", lpreobject->cp);
ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor);
if (!cursor.pRun->member.run.reobj)
return E_INVALIDARG;
else
reobj = cursor.pRun->member.run.reobj;
}
else
{
if (iob > IRichEditOle_GetObjectCount(me))
return E_INVALIDARG;
LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
{
if (count == iob)
break;
count++;
}
}
ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
return S_OK;
}
static LONG WINAPI
IRichEditOle_fnGetObjectCount(IRichEditOle *me)
{
IRichEditOleImpl *This = impl_from_IRichEditOle(me);
FIXME("stub %p\n",This);
return 0;
TRACE("(%p)\n",This);
return list_count(&This->editor->reobj_list);
}
static HRESULT WINAPI
@ -2170,17 +2200,63 @@ static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG cou
return E_NOTIMPL;
}
static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG *delta)
{
LONG old_start, old_end, new_start, new_end;
HRESULT hr = S_OK;
if (!count)
{
if (delta)
*delta = 0;
return S_FALSE;
}
ITextRange_GetStart(range, &old_start);
ITextRange_GetEnd(range, &old_end);
switch (unit)
{
case tomStory:
if (count < 0)
new_start = new_end = 0;
else
{
new_start = old_start;
ITextRange_GetStoryLength(range, &new_end);
}
if (delta)
{
if (new_end < old_end)
*delta = -1;
else if (new_end == old_end)
*delta = 0;
else
*delta = 1;
}
break;
default:
FIXME("unit %d is not supported\n", unit);
return E_NOTIMPL;
}
if (new_end == old_end)
hr = S_FALSE;
ITextRange_SetStart(range, new_start);
ITextRange_SetEnd(range, new_end);
return hr;
}
static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
LONG *delta)
{
ITextRangeImpl *This = impl_from_ITextRange(me);
FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
if (!This->child.reole)
return CO_E_RELEASED;
return E_NOTIMPL;
return textrange_moveend(me, unit, count, delta);
}
static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
@ -4650,6 +4726,8 @@ static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
ITextRange *range = NULL;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, font);
@ -4659,12 +4737,16 @@ static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **f
if (!font)
return E_INVALIDARG;
return create_textfont((ITextRange*)me, NULL, font);
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
hr = create_textfont(range, NULL, font);
ITextRange_Release(range);
return hr;
}
static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
ITextRange *range = NULL;
TRACE("(%p)->(%p)\n", This, font);
@ -4674,13 +4756,17 @@ static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *fo
if (!This->reOle)
return CO_E_RELEASED;
textrange_set_font((ITextRange*)me, font);
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
textrange_set_font(range, font);
ITextRange_Release(range);
return S_OK;
}
static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
ITextRange *range = NULL;
HRESULT hr;
TRACE("(%p)->(%p)\n", This, para);
@ -4690,7 +4776,10 @@ static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **p
if (!para)
return E_INVALIDARG;
return create_textpara((ITextRange*)me, para);
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
hr = create_textpara(range, para);
ITextRange_Release(range);
return hr;
}
static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
@ -4755,13 +4844,18 @@ static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
ITextRange *range = NULL;
HRESULT hr;
TRACE("(%p)->(%d %p)\n", This, unit, delta);
if (!This->reOle)
return CO_E_RELEASED;
return textrange_expand((ITextRange*)me, unit, delta);
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
hr = textrange_expand(range, unit, delta);
ITextRange_Release(range);
return hr;
}
static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
@ -4935,13 +5029,18 @@ static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LO
LONG *delta)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
ITextRange *range = NULL;
HRESULT hr;
FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
if (!This->reOle)
return CO_E_RELEASED;
return E_NOTIMPL;
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
hr = textrange_moveend(range, unit, count, delta);
ITextRange_Release(range);
return hr;
}
static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
@ -5456,11 +5555,11 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
ENHMETAHEADER emh;
assert(run->nFlags & MERF_GRAPHICS);
assert(run->ole_obj);
assert(run->reobj);
if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
{
convert_sizel(c, &run->ole_obj->sizel, pSize);
convert_sizel(c, &run->reobj->obj.sizel, pSize);
if (c->editor->nZoomNumerator != 0)
{
pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
@ -5469,13 +5568,13 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
return;
}
if (!run->ole_obj->poleobj)
if (!run->reobj->obj.poleobj)
{
pSize->cx = pSize->cy = 0;
return;
}
if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
{
FIXME("Query Interface IID_IDataObject failed!\n");
pSize->cx = pSize->cy = 0;
@ -5538,13 +5637,13 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
RECT rc;
assert(run->nFlags & MERF_GRAPHICS);
assert(run->ole_obj);
if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
assert(run->reobj);
if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
{
FIXME("Couldn't get interface\n");
return;
}
has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
fmt.cfFormat = CF_BITMAP;
fmt.ptd = NULL;
fmt.dwAspect = DVASPECT_CONTENT;
@ -5571,7 +5670,7 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
if (has_size)
{
convert_sizel(c, &run->ole_obj->sizel, &sz);
convert_sizel(c, &run->reobj->obj.sizel, &sz);
} else {
sz.cx = dibsect.dsBm.bmWidth;
sz.cy = dibsect.dsBm.bmHeight;
@ -5591,7 +5690,7 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
if (has_size)
{
convert_sizel(c, &run->ole_obj->sizel, &sz);
convert_sizel(c, &run->reobj->obj.sizel, &sz);
} else {
sz.cx = emh.rclBounds.right - emh.rclBounds.left;
sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
@ -5619,21 +5718,36 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
}
void ME_DeleteReObject(REOBJECT* reo)
void ME_DeleteReObject(struct re_object *reobj)
{
if (reo->poleobj) IOleObject_Release(reo->poleobj);
if (reo->pstg) IStorage_Release(reo->pstg);
if (reo->polesite) IOleClientSite_Release(reo->polesite);
heap_free(reo);
if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj);
if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg);
if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite);
heap_free(reobj);
}
void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
{
*dst = *src;
dst->poleobj = NULL;
dst->pstg = NULL;
dst->polesite = NULL;
if (dst->poleobj) IOleObject_AddRef(dst->poleobj);
if (dst->pstg) IStorage_AddRef(dst->pstg);
if (dst->polesite) IOleClientSite_AddRef(dst->polesite);
if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
{
dst->poleobj = src->poleobj;
IOleObject_AddRef(dst->poleobj);
}
if ((flags & REO_GETOBJ_PSTG) && src->pstg)
{
dst->pstg = src->pstg;
IStorage_AddRef(dst->pstg);
}
if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
{
dst->polesite = src->polesite;
IOleClientSite_AddRef(dst->polesite);
}
}
void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)

View file

@ -295,7 +295,7 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, int nFlags)
{
ME_DisplayItem *item = ME_MakeDI(diRun);
item->member.run.style = s;
item->member.run.ole_obj = NULL;
item->member.run.reobj = NULL;
item->member.run.nFlags = nFlags;
item->member.run.nCharOfs = -1;
item->member.run.len = 0;

View file

@ -947,7 +947,7 @@ static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream,
SIZE goal, pic;
ME_Context c;
hr = IOleObject_QueryInterface( run->ole_obj->poleobj, &IID_IDataObject, (void **)&data );
hr = IOleObject_QueryInterface( run->reobj->obj.poleobj, &IID_IDataObject, (void **)&data );
if (FAILED(hr)) return FALSE;
ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) );
@ -975,8 +975,8 @@ static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream,
emf_bits->szlMillimeters.cy * c.dpi.cy * 10 );
/* convert goal size to twips */
goal.cx = MulDiv( run->ole_obj->sizel.cx, 144, 254 );
goal.cy = MulDiv( run->ole_obj->sizel.cy, 144, 254 );
goal.cx = MulDiv( run->reobj->obj.sizel.cx, 144, 254 );
goal.cy = MulDiv( run->reobj->obj.sizel.cy, 144, 254 );
if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n",
pic.cx, pic.cy, goal.cx, goal.cy ))

View file

@ -158,7 +158,7 @@ reactos/dll/win32/qmgrprxy # Synced to WineStaging-2.9
reactos/dll/win32/query # Synced to WineStaging-3.3
reactos/dll/win32/rasapi32 # Synced to WineStaging-3.3
reactos/dll/win32/resutils # Synced to WineStaging-3.3
reactos/dll/win32/riched20 # Synced to WineStaging-3.3
reactos/dll/win32/riched20 # Synced to WineStaging-3.9
reactos/dll/win32/riched32 # Synced to WineStaging-3.3
reactos/dll/win32/rpcrt4 # Synced to WineStaging-3.3
reactos/dll/win32/rsabase # Synced to WineStaging-3.3