5873 lines
160 KiB
C
5873 lines
160 KiB
C
/*
|
|
* RichEdit GUIDs and OLE interface
|
|
*
|
|
* Copyright 2004 by Krzysztof Foltman
|
|
* Copyright 2004 Aric Stewart
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#define NONAMELESSUNION
|
|
#define COBJMACROS
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#include "winuser.h"
|
|
#include "ole2.h"
|
|
#include "richole.h"
|
|
#include "editor.h"
|
|
#include "richedit.h"
|
|
#include "tom.h"
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
|
|
|
|
/* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
|
|
|
|
#include "initguid.h"
|
|
|
|
DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
|
|
DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
|
|
DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
|
|
DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
|
|
DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
|
|
DEFINE_GUID(IID_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
|
|
DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
|
|
DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
|
|
DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
|
|
DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
|
|
|
|
static ITypeLib *typelib;
|
|
|
|
enum tid_t {
|
|
NULL_tid,
|
|
ITextDocument_tid,
|
|
ITextRange_tid,
|
|
ITextSelection_tid,
|
|
ITextFont_tid,
|
|
ITextPara_tid,
|
|
LAST_tid
|
|
};
|
|
|
|
static const IID * const tid_ids[] =
|
|
{
|
|
&IID_NULL,
|
|
&IID_ITextDocument,
|
|
&IID_ITextRange,
|
|
&IID_ITextSelection,
|
|
&IID_ITextFont,
|
|
&IID_ITextPara,
|
|
};
|
|
static ITypeInfo *typeinfos[LAST_tid];
|
|
|
|
static HRESULT load_typelib(void)
|
|
{
|
|
ITypeLib *tl;
|
|
HRESULT hr;
|
|
|
|
hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
|
|
if (FAILED(hr)) {
|
|
ERR("LoadRegTypeLib failed: %08lx\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
|
|
ITypeLib_Release(tl);
|
|
return hr;
|
|
}
|
|
|
|
void release_typelib(void)
|
|
{
|
|
unsigned i;
|
|
|
|
if (!typelib)
|
|
return;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
|
|
if (typeinfos[i])
|
|
ITypeInfo_Release(typeinfos[i]);
|
|
|
|
ITypeLib_Release(typelib);
|
|
}
|
|
|
|
static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!typelib)
|
|
hr = load_typelib();
|
|
if (!typelib)
|
|
return hr;
|
|
|
|
if (!typeinfos[tid])
|
|
{
|
|
ITypeInfo *ti;
|
|
|
|
hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
|
|
if (FAILED(hr))
|
|
{
|
|
ERR("GetTypeInfoOfGuid(%s) failed: %08lx\n", debugstr_guid(tid_ids[tid]), hr);
|
|
return hr;
|
|
}
|
|
|
|
if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
|
|
ITypeInfo_Release(ti);
|
|
}
|
|
|
|
*typeinfo = typeinfos[tid];
|
|
return S_OK;
|
|
}
|
|
|
|
/* private IID used to get back IRichEditOleImpl pointer */
|
|
DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
|
|
|
|
typedef struct IOleClientSiteImpl IOleClientSiteImpl;
|
|
typedef struct ITextRangeImpl ITextRangeImpl;
|
|
|
|
enum textfont_prop_id {
|
|
FONT_ALLCAPS = 0,
|
|
FONT_ANIMATION,
|
|
FONT_BACKCOLOR,
|
|
FONT_BOLD,
|
|
FONT_EMBOSS,
|
|
FONT_FORECOLOR,
|
|
FONT_HIDDEN,
|
|
FONT_ENGRAVE,
|
|
FONT_ITALIC,
|
|
FONT_KERNING,
|
|
FONT_LANGID,
|
|
FONT_NAME,
|
|
FONT_OUTLINE,
|
|
FONT_POSITION,
|
|
FONT_PROTECTED,
|
|
FONT_SHADOW,
|
|
FONT_SIZE,
|
|
FONT_SMALLCAPS,
|
|
FONT_SPACING,
|
|
FONT_STRIKETHROUGH,
|
|
FONT_SUBSCRIPT,
|
|
FONT_SUPERSCRIPT,
|
|
FONT_UNDERLINE,
|
|
FONT_WEIGHT,
|
|
FONT_PROPID_LAST,
|
|
FONT_PROPID_FIRST = FONT_ALLCAPS
|
|
};
|
|
|
|
static const DWORD textfont_prop_masks[][2] = {
|
|
{ CFM_ALLCAPS, CFE_ALLCAPS },
|
|
{ CFM_ANIMATION },
|
|
{ CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
|
|
{ CFM_BOLD, CFE_BOLD },
|
|
{ CFM_EMBOSS, CFE_EMBOSS },
|
|
{ CFM_COLOR, CFE_AUTOCOLOR },
|
|
{ CFM_HIDDEN, CFE_HIDDEN },
|
|
{ CFM_IMPRINT, CFE_IMPRINT },
|
|
{ CFM_ITALIC, CFE_ITALIC },
|
|
{ CFM_KERNING },
|
|
{ CFM_LCID },
|
|
{ CFM_FACE },
|
|
{ CFM_OUTLINE, CFE_OUTLINE },
|
|
{ CFM_OFFSET },
|
|
{ CFM_PROTECTED, CFE_PROTECTED },
|
|
{ CFM_SHADOW, CFE_SHADOW },
|
|
{ CFM_SIZE },
|
|
{ CFM_SMALLCAPS, CFE_SMALLCAPS },
|
|
{ CFM_SPACING },
|
|
{ CFM_STRIKEOUT, CFE_STRIKEOUT },
|
|
{ CFM_SUBSCRIPT, CFE_SUBSCRIPT },
|
|
{ CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
|
|
{ CFM_UNDERLINE, CFE_UNDERLINE },
|
|
{ CFM_WEIGHT }
|
|
};
|
|
|
|
typedef union {
|
|
FLOAT f;
|
|
LONG l;
|
|
BSTR str;
|
|
} textfont_prop_val;
|
|
|
|
enum range_update_op {
|
|
RANGE_UPDATE_DELETE
|
|
};
|
|
|
|
struct reole_child {
|
|
struct list entry;
|
|
struct text_services *reole;
|
|
};
|
|
|
|
struct ITextRangeImpl {
|
|
struct reole_child child;
|
|
ITextRange ITextRange_iface;
|
|
LONG ref;
|
|
LONG start, end;
|
|
};
|
|
|
|
typedef struct ITextFontImpl {
|
|
ITextFont ITextFont_iface;
|
|
LONG ref;
|
|
|
|
ITextRange *range;
|
|
textfont_prop_val props[FONT_PROPID_LAST];
|
|
BOOL get_cache_enabled;
|
|
BOOL set_cache_enabled;
|
|
} ITextFontImpl;
|
|
|
|
typedef struct ITextParaImpl {
|
|
ITextPara ITextPara_iface;
|
|
LONG ref;
|
|
|
|
ITextRange *range;
|
|
} ITextParaImpl;
|
|
|
|
struct IOleClientSiteImpl {
|
|
struct reole_child child;
|
|
IOleClientSite IOleClientSite_iface;
|
|
IOleInPlaceSite IOleInPlaceSite_iface;
|
|
LONG ref;
|
|
};
|
|
|
|
static inline struct text_services *impl_from_IRichEditOle( IRichEditOle *iface )
|
|
{
|
|
return CONTAINING_RECORD( iface, struct text_services, IRichEditOle_iface );
|
|
}
|
|
|
|
static inline struct text_services *impl_from_ITextDocument2Old( ITextDocument2Old *iface )
|
|
{
|
|
return CONTAINING_RECORD( iface, struct text_services, ITextDocument2Old_iface );
|
|
}
|
|
|
|
static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
|
|
}
|
|
|
|
static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
|
|
}
|
|
|
|
static inline struct text_selection *impl_from_ITextSelection(ITextSelection *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, struct text_selection, ITextSelection_iface);
|
|
}
|
|
|
|
static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
|
|
}
|
|
|
|
static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
|
|
}
|
|
|
|
static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
|
|
static HRESULT create_textpara(ITextRange*, ITextPara**);
|
|
static struct text_selection *text_selection_create( struct text_services * );
|
|
|
|
static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
|
|
{
|
|
if (!length)
|
|
return E_INVALIDARG;
|
|
|
|
*length = ME_GetTextLength(editor) + 1;
|
|
return S_OK;
|
|
}
|
|
|
|
static void textranges_update_ranges(struct text_services *services, LONG start, LONG end, enum range_update_op op)
|
|
{
|
|
ITextRangeImpl *range;
|
|
|
|
LIST_FOR_EACH_ENTRY(range, &services->rangelist, ITextRangeImpl, child.entry) {
|
|
switch (op)
|
|
{
|
|
case RANGE_UPDATE_DELETE:
|
|
/* range fully covered by deleted range - collapse to insertion point */
|
|
if (range->start >= start && range->end <= end)
|
|
range->start = range->end = start;
|
|
/* deleted range cuts from the right */
|
|
else if (range->start < start && range->end <= end)
|
|
range->end = start;
|
|
/* deleted range cuts from the left */
|
|
else if (range->start >= start && range->end > end) {
|
|
range->start = start;
|
|
range->end -= end - start;
|
|
}
|
|
/* deleted range cuts within */
|
|
else
|
|
range->end -= end - start;
|
|
break;
|
|
default:
|
|
FIXME("unknown update op, %d\n", op);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
|
|
textfont_prop_val *right)
|
|
{
|
|
switch (propid)
|
|
{
|
|
case FONT_ALLCAPS:
|
|
case FONT_ANIMATION:
|
|
case FONT_BACKCOLOR:
|
|
case FONT_BOLD:
|
|
case FONT_EMBOSS:
|
|
case FONT_FORECOLOR:
|
|
case FONT_HIDDEN:
|
|
case FONT_ENGRAVE:
|
|
case FONT_ITALIC:
|
|
case FONT_KERNING:
|
|
case FONT_LANGID:
|
|
case FONT_OUTLINE:
|
|
case FONT_PROTECTED:
|
|
case FONT_SHADOW:
|
|
case FONT_SMALLCAPS:
|
|
case FONT_STRIKETHROUGH:
|
|
case FONT_SUBSCRIPT:
|
|
case FONT_SUPERSCRIPT:
|
|
case FONT_UNDERLINE:
|
|
case FONT_WEIGHT:
|
|
return left->l == right->l;
|
|
case FONT_NAME:
|
|
return !wcscmp(left->str, right->str);
|
|
case FONT_POSITION:
|
|
case FONT_SIZE:
|
|
case FONT_SPACING:
|
|
return left->f == right->f;
|
|
default:
|
|
FIXME("unhandled font property %d\n", propid);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
|
|
{
|
|
switch (propid)
|
|
{
|
|
case FONT_ALLCAPS:
|
|
case FONT_ANIMATION:
|
|
case FONT_BACKCOLOR:
|
|
case FONT_BOLD:
|
|
case FONT_EMBOSS:
|
|
case FONT_FORECOLOR:
|
|
case FONT_HIDDEN:
|
|
case FONT_ENGRAVE:
|
|
case FONT_ITALIC:
|
|
case FONT_KERNING:
|
|
case FONT_LANGID:
|
|
case FONT_OUTLINE:
|
|
case FONT_PROTECTED:
|
|
case FONT_SHADOW:
|
|
case FONT_SMALLCAPS:
|
|
case FONT_STRIKETHROUGH:
|
|
case FONT_SUBSCRIPT:
|
|
case FONT_SUPERSCRIPT:
|
|
case FONT_UNDERLINE:
|
|
case FONT_WEIGHT:
|
|
v->l = tomUndefined;
|
|
return;
|
|
case FONT_NAME:
|
|
v->str = NULL;
|
|
return;
|
|
case FONT_POSITION:
|
|
case FONT_SIZE:
|
|
case FONT_SPACING:
|
|
v->f = tomUndefined;
|
|
return;
|
|
default:
|
|
FIXME("unhandled font property %d\n", propid);
|
|
v->l = tomUndefined;
|
|
return;
|
|
}
|
|
}
|
|
|
|
static inline FLOAT twips_to_points(LONG value)
|
|
{
|
|
return value * 72.0 / 1440;
|
|
}
|
|
|
|
static inline FLOAT points_to_twips(FLOAT value)
|
|
{
|
|
return value * 1440 / 72.0;
|
|
}
|
|
|
|
static HRESULT get_textfont_prop_for_pos(const struct text_services *services, int pos, enum textfont_prop_id propid,
|
|
textfont_prop_val *value)
|
|
{
|
|
ME_Cursor from, to;
|
|
CHARFORMAT2W fmt;
|
|
|
|
memset(&fmt, 0, sizeof(fmt));
|
|
fmt.cbSize = sizeof(fmt);
|
|
fmt.dwMask = textfont_prop_masks[propid][0];
|
|
|
|
cursor_from_char_ofs( services->editor, pos, &from );
|
|
to = from;
|
|
ME_MoveCursorChars( services->editor, &to, 1, FALSE );
|
|
ME_GetCharFormat( services->editor, &from, &to, &fmt );
|
|
|
|
switch (propid)
|
|
{
|
|
case FONT_ALLCAPS:
|
|
case FONT_BOLD:
|
|
case FONT_EMBOSS:
|
|
case FONT_HIDDEN:
|
|
case FONT_ENGRAVE:
|
|
case FONT_ITALIC:
|
|
case FONT_OUTLINE:
|
|
case FONT_PROTECTED:
|
|
case FONT_SHADOW:
|
|
case FONT_SMALLCAPS:
|
|
case FONT_STRIKETHROUGH:
|
|
case FONT_SUBSCRIPT:
|
|
case FONT_SUPERSCRIPT:
|
|
case FONT_UNDERLINE:
|
|
value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
|
|
break;
|
|
case FONT_ANIMATION:
|
|
value->l = fmt.bAnimation;
|
|
break;
|
|
case FONT_BACKCOLOR:
|
|
value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
|
|
break;
|
|
case FONT_FORECOLOR:
|
|
value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
|
|
break;
|
|
case FONT_KERNING:
|
|
value->f = twips_to_points(fmt.wKerning);
|
|
break;
|
|
case FONT_LANGID:
|
|
value->l = fmt.lcid;
|
|
break;
|
|
case FONT_NAME:
|
|
/* this case is used exclusively by GetName() */
|
|
value->str = SysAllocString(fmt.szFaceName);
|
|
if (!value->str)
|
|
return E_OUTOFMEMORY;
|
|
break;
|
|
case FONT_POSITION:
|
|
value->f = twips_to_points(fmt.yOffset);
|
|
break;
|
|
case FONT_SIZE:
|
|
value->f = twips_to_points(fmt.yHeight);
|
|
break;
|
|
case FONT_SPACING:
|
|
value->f = fmt.sSpacing;
|
|
break;
|
|
case FONT_WEIGHT:
|
|
value->l = fmt.wWeight;
|
|
break;
|
|
default:
|
|
FIXME("unhandled font property %d\n", propid);
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static inline const struct text_services *get_range_reole(ITextRange *range)
|
|
{
|
|
struct text_services *services = NULL;
|
|
ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&services);
|
|
return services;
|
|
}
|
|
|
|
static void textrange_set_font(ITextRange *range, ITextFont *font)
|
|
{
|
|
CHARFORMAT2W fmt;
|
|
HRESULT hr;
|
|
LONG value;
|
|
BSTR str;
|
|
FLOAT f;
|
|
|
|
#define CHARFORMAT_SET_B_FIELD(mask, value) \
|
|
if (hr == S_OK && value != tomUndefined) { \
|
|
fmt.dwMask |= CFM_##mask; \
|
|
if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
|
|
} \
|
|
|
|
/* fill format data from font */
|
|
memset(&fmt, 0, sizeof(fmt));
|
|
fmt.cbSize = sizeof(fmt);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetAllCaps(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetBold(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(BOLD, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetEmboss(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(EMBOSS, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetHidden(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(HIDDEN, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetEngrave(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(IMPRINT, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetItalic(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(ITALIC, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetOutline(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(OUTLINE, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetProtected(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(PROTECTED, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetShadow(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(SHADOW, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetSmallCaps(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetStrikeThrough(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetSubscript(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetSuperscript(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetUnderline(font, &value);
|
|
CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
|
|
|
|
#undef CHARFORMAT_SET_B_FIELD
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetAnimation(font, &value);
|
|
if (hr == S_OK && value != tomUndefined) {
|
|
fmt.dwMask |= CFM_ANIMATION;
|
|
fmt.bAnimation = value;
|
|
}
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetBackColor(font, &value);
|
|
if (hr == S_OK && value != tomUndefined) {
|
|
fmt.dwMask |= CFM_BACKCOLOR;
|
|
if (value == tomAutoColor)
|
|
fmt.dwEffects |= CFE_AUTOBACKCOLOR;
|
|
else
|
|
fmt.crBackColor = value;
|
|
}
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetForeColor(font, &value);
|
|
if (hr == S_OK && value != tomUndefined) {
|
|
fmt.dwMask |= CFM_COLOR;
|
|
if (value == tomAutoColor)
|
|
fmt.dwEffects |= CFE_AUTOCOLOR;
|
|
else
|
|
fmt.crTextColor = value;
|
|
}
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetKerning(font, &f);
|
|
if (hr == S_OK && f != tomUndefined) {
|
|
fmt.dwMask |= CFM_KERNING;
|
|
fmt.wKerning = points_to_twips(f);
|
|
}
|
|
|
|
value = tomUndefined;
|
|
hr = ITextFont_GetLanguageID(font, &value);
|
|
if (hr == S_OK && value != tomUndefined) {
|
|
fmt.dwMask |= CFM_LCID;
|
|
fmt.lcid = value;
|
|
}
|
|
|
|
if (ITextFont_GetName(font, &str) == S_OK) {
|
|
fmt.dwMask |= CFM_FACE;
|
|
lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
|
|
SysFreeString(str);
|
|
}
|
|
|
|
hr = ITextFont_GetPosition(font, &f);
|
|
if (hr == S_OK && f != tomUndefined) {
|
|
fmt.dwMask |= CFM_OFFSET;
|
|
fmt.yOffset = points_to_twips(f);
|
|
}
|
|
|
|
hr = ITextFont_GetSize(font, &f);
|
|
if (hr == S_OK && f != tomUndefined) {
|
|
fmt.dwMask |= CFM_SIZE;
|
|
fmt.yHeight = points_to_twips(f);
|
|
}
|
|
|
|
hr = ITextFont_GetSpacing(font, &f);
|
|
if (hr == S_OK && f != tomUndefined) {
|
|
fmt.dwMask |= CFM_SPACING;
|
|
fmt.sSpacing = f;
|
|
}
|
|
|
|
hr = ITextFont_GetWeight(font, &value);
|
|
if (hr == S_OK && value != tomUndefined) {
|
|
fmt.dwMask |= CFM_WEIGHT;
|
|
fmt.wWeight = value;
|
|
}
|
|
|
|
if (fmt.dwMask)
|
|
{
|
|
const struct text_services *services = get_range_reole(range);
|
|
ME_Cursor from, to;
|
|
LONG start, end;
|
|
|
|
ITextRange_GetStart(range, &start);
|
|
ITextRange_GetEnd(range, &end);
|
|
|
|
cursor_from_char_ofs( services->editor, start, &from );
|
|
cursor_from_char_ofs( services->editor, end, &to );
|
|
ME_SetCharFormat( services->editor, &from, &to, &fmt );
|
|
}
|
|
}
|
|
|
|
static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
|
|
{
|
|
const struct text_services *services;
|
|
textfont_prop_val v;
|
|
LONG start, end, i;
|
|
HRESULT hr;
|
|
|
|
/* when font is not attached to any range use cached values */
|
|
if (!font->range || font->get_cache_enabled) {
|
|
*value = font->props[propid];
|
|
return S_OK;
|
|
}
|
|
|
|
if (!(services = get_range_reole(font->range)))
|
|
return CO_E_RELEASED;
|
|
|
|
init_textfont_prop_value(propid, value);
|
|
|
|
ITextRange_GetStart(font->range, &start);
|
|
ITextRange_GetEnd(font->range, &end);
|
|
|
|
/* iterate trough a range to see if property value is consistent */
|
|
hr = get_textfont_prop_for_pos( services, start, propid, &v );
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
for (i = start + 1; i < end; i++) {
|
|
textfont_prop_val cur;
|
|
|
|
hr = get_textfont_prop_for_pos( services, i, propid, &cur );
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
if (!is_equal_textfont_prop_value(propid, &v, &cur))
|
|
return S_OK;
|
|
}
|
|
|
|
*value = v;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
|
|
{
|
|
textfont_prop_val v;
|
|
HRESULT hr;
|
|
|
|
if (!value)
|
|
return E_INVALIDARG;
|
|
|
|
hr = get_textfont_prop(font, propid, &v);
|
|
*value = v.f;
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
|
|
{
|
|
textfont_prop_val v;
|
|
HRESULT hr;
|
|
|
|
if (!value)
|
|
return E_INVALIDARG;
|
|
|
|
hr = get_textfont_prop(font, propid, &v);
|
|
*value = v.l;
|
|
return hr;
|
|
}
|
|
|
|
/* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
|
|
static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
|
|
{
|
|
const struct text_services *services;
|
|
ME_Cursor from, to;
|
|
CHARFORMAT2W fmt;
|
|
LONG start, end;
|
|
|
|
/* when font is not attached to any range use cache */
|
|
if (!font->range || font->set_cache_enabled) {
|
|
if (propid == FONT_NAME) {
|
|
SysFreeString(font->props[propid].str);
|
|
font->props[propid].str = SysAllocString(value->str);
|
|
}
|
|
else
|
|
font->props[propid] = *value;
|
|
return S_OK;
|
|
}
|
|
|
|
if (!(services = get_range_reole(font->range)))
|
|
return CO_E_RELEASED;
|
|
|
|
memset(&fmt, 0, sizeof(fmt));
|
|
fmt.cbSize = sizeof(fmt);
|
|
fmt.dwMask = textfont_prop_masks[propid][0];
|
|
|
|
switch (propid)
|
|
{
|
|
case FONT_ALLCAPS:
|
|
case FONT_BOLD:
|
|
case FONT_EMBOSS:
|
|
case FONT_HIDDEN:
|
|
case FONT_ENGRAVE:
|
|
case FONT_ITALIC:
|
|
case FONT_OUTLINE:
|
|
case FONT_PROTECTED:
|
|
case FONT_SHADOW:
|
|
case FONT_SMALLCAPS:
|
|
case FONT_STRIKETHROUGH:
|
|
case FONT_SUBSCRIPT:
|
|
case FONT_SUPERSCRIPT:
|
|
case FONT_UNDERLINE:
|
|
fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
|
|
break;
|
|
case FONT_ANIMATION:
|
|
fmt.bAnimation = value->l;
|
|
break;
|
|
case FONT_BACKCOLOR:
|
|
case FONT_FORECOLOR:
|
|
if (value->l == tomAutoColor)
|
|
fmt.dwEffects = textfont_prop_masks[propid][1];
|
|
else if (propid == FONT_BACKCOLOR)
|
|
fmt.crBackColor = value->l;
|
|
else
|
|
fmt.crTextColor = value->l;
|
|
break;
|
|
case FONT_KERNING:
|
|
fmt.wKerning = value->f;
|
|
break;
|
|
case FONT_LANGID:
|
|
fmt.lcid = value->l;
|
|
break;
|
|
case FONT_POSITION:
|
|
fmt.yOffset = value->f;
|
|
break;
|
|
case FONT_SIZE:
|
|
fmt.yHeight = value->f;
|
|
break;
|
|
case FONT_SPACING:
|
|
fmt.sSpacing = value->f;
|
|
break;
|
|
case FONT_WEIGHT:
|
|
fmt.wWeight = value->l;
|
|
break;
|
|
case FONT_NAME:
|
|
lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
|
|
break;
|
|
default:
|
|
FIXME("unhandled font property %d\n", propid);
|
|
return E_FAIL;
|
|
}
|
|
|
|
ITextRange_GetStart(font->range, &start);
|
|
ITextRange_GetEnd(font->range, &end);
|
|
|
|
cursor_from_char_ofs( services->editor, start, &from );
|
|
cursor_from_char_ofs( services->editor, end, &to );
|
|
ME_SetCharFormat( services->editor, &from, &to, &fmt );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
|
|
{
|
|
textfont_prop_val v;
|
|
v.l = value;
|
|
return set_textfont_prop(font, propid, &v);
|
|
}
|
|
|
|
static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
|
|
{
|
|
textfont_prop_val v;
|
|
v.f = value;
|
|
return set_textfont_prop(font, propid, &v);
|
|
}
|
|
|
|
static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
|
|
{
|
|
textfont_prop_val v;
|
|
|
|
switch (value)
|
|
{
|
|
case tomUndefined:
|
|
return S_OK;
|
|
case tomToggle: {
|
|
LONG oldvalue;
|
|
get_textfont_propl(font, propid, &oldvalue);
|
|
if (oldvalue == tomFalse)
|
|
value = tomTrue;
|
|
else if (oldvalue == tomTrue)
|
|
value = tomFalse;
|
|
else
|
|
return E_INVALIDARG;
|
|
/* fallthrough */
|
|
}
|
|
case tomTrue:
|
|
case tomFalse:
|
|
v.l = value;
|
|
return set_textfont_prop(font, propid, &v);
|
|
default:
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
|
|
{
|
|
const struct text_services *services;
|
|
textfont_prop_val v;
|
|
HRESULT hr;
|
|
LONG start;
|
|
|
|
if (!(services = get_range_reole( range )))
|
|
return CO_E_RELEASED;
|
|
|
|
ITextRange_GetStart(range, &start);
|
|
hr = get_textfont_prop_for_pos( services, start, FONT_NAME, &v );
|
|
*ret = v.str;
|
|
return hr;
|
|
}
|
|
|
|
static void textfont_cache_range_props(ITextFontImpl *font)
|
|
{
|
|
enum textfont_prop_id propid;
|
|
for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
|
|
if (propid == FONT_NAME)
|
|
textfont_getname_from_range(font->range, &font->props[propid].str);
|
|
else
|
|
get_textfont_prop(font, propid, &font->props[propid]);
|
|
}
|
|
}
|
|
|
|
static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
|
|
{
|
|
LONG expand_start, expand_end;
|
|
|
|
switch (unit)
|
|
{
|
|
case tomStory:
|
|
expand_start = 0;
|
|
ITextRange_GetStoryLength(range, &expand_end);
|
|
break;
|
|
default:
|
|
FIXME("unit %ld is not supported\n", unit);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
if (delta) {
|
|
LONG start, end;
|
|
|
|
ITextRange_GetStart(range, &start);
|
|
ITextRange_GetEnd(range, &end);
|
|
*delta = expand_end - expand_start - (end - start);
|
|
}
|
|
|
|
ITextRange_SetStart(range, expand_start);
|
|
ITextRange_SetEnd(range, expand_end);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnQueryInterface(IRichEditOle *iface, REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
return IUnknown_QueryInterface( services->outer_unk, riid, ppvObj );
|
|
}
|
|
|
|
static ULONG WINAPI
|
|
IRichEditOle_fnAddRef(IRichEditOle *iface)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
return IUnknown_AddRef( services->outer_unk );
|
|
}
|
|
|
|
static ULONG WINAPI
|
|
IRichEditOle_fnRelease(IRichEditOle *iface)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
return IUnknown_Release( services->outer_unk );
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnActivateAs(IRichEditOle *iface, REFCLSID rclsid, REFCLSID rclsidAs)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME( "stub %p\n", services );
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnContextSensitiveHelp(IRichEditOle *iface, BOOL fEnterMode)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME( "stub %p\n", services );
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnConvertObject( IRichEditOle *iface, LONG iob, REFCLSID class, LPCSTR user_type )
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME( "stub %p\n", services );
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
|
|
TRACE("%p %s\n", me, debugstr_guid(riid) );
|
|
|
|
*ppvObj = NULL;
|
|
if (IsEqualGUID(riid, &IID_IUnknown) ||
|
|
IsEqualGUID(riid, &IID_IOleClientSite))
|
|
*ppvObj = me;
|
|
else if (IsEqualGUID(riid, &IID_IOleWindow) ||
|
|
IsEqualGUID(riid, &IID_IOleInPlaceSite))
|
|
*ppvObj = &This->IOleInPlaceSite_iface;
|
|
if (*ppvObj)
|
|
{
|
|
IOleClientSite_AddRef(me);
|
|
return S_OK;
|
|
}
|
|
FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
ULONG ref = InterlockedIncrement(&This->ref);
|
|
TRACE("(%p)->(%lu)\n", This, ref);
|
|
return ref;
|
|
}
|
|
|
|
static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("(%p)->(%lu)\n", This, ref);
|
|
|
|
if (ref == 0) {
|
|
if (This->child.reole) {
|
|
list_remove(&This->child.entry);
|
|
This->child.reole = NULL;
|
|
}
|
|
heap_free(This);
|
|
}
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("stub %p\n", iface);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
|
|
DWORD dwWhichMoniker, IMoniker **ppmk)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("stub %p\n", iface);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
|
|
IOleContainer **ppContainer)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("stub %p\n", iface);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("stub %p\n", iface);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("stub %p\n", iface);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("stub %p\n", iface);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const IOleClientSiteVtbl ocst = {
|
|
IOleClientSite_fnQueryInterface,
|
|
IOleClientSite_fnAddRef,
|
|
IOleClientSite_fnRelease,
|
|
IOleClientSite_fnSaveObject,
|
|
IOleClientSite_fnGetMoniker,
|
|
IOleClientSite_fnGetContainer,
|
|
IOleClientSite_fnShowObject,
|
|
IOleClientSite_fnOnShowWindow,
|
|
IOleClientSite_fnRequestNewObjectLayout
|
|
};
|
|
|
|
/* IOleInPlaceSite interface */
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
return IOleClientSite_AddRef(&This->IOleClientSite_iface);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
return IOleClientSite_Release(&This->IOleClientSite_iface);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow( IOleInPlaceSite *iface, HWND *window )
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
|
|
TRACE( "(%p)->(%p)\n", This, window );
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!window) return E_INVALIDARG;
|
|
|
|
if (!This->child.reole->editor->have_texthost2) return E_NOTIMPL;
|
|
return ITextHost2_TxGetWindow( This->child.reole->editor->texthost, window );
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
|
|
IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
|
|
LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
|
|
{
|
|
IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
|
|
FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const IOleInPlaceSiteVtbl olestvt =
|
|
{
|
|
IOleInPlaceSite_fnQueryInterface,
|
|
IOleInPlaceSite_fnAddRef,
|
|
IOleInPlaceSite_fnRelease,
|
|
IOleInPlaceSite_fnGetWindow,
|
|
IOleInPlaceSite_fnContextSensitiveHelp,
|
|
IOleInPlaceSite_fnCanInPlaceActivate,
|
|
IOleInPlaceSite_fnOnInPlaceActivate,
|
|
IOleInPlaceSite_fnOnUIActivate,
|
|
IOleInPlaceSite_fnGetWindowContext,
|
|
IOleInPlaceSite_fnScroll,
|
|
IOleInPlaceSite_fnOnUIDeactivate,
|
|
IOleInPlaceSite_fnOnInPlaceDeactivate,
|
|
IOleInPlaceSite_fnDiscardUndoState,
|
|
IOleInPlaceSite_fnDeactivateAndUndo,
|
|
IOleInPlaceSite_fnOnPosRectChange
|
|
};
|
|
|
|
static HRESULT CreateOleClientSite( struct text_services *services, IOleClientSite **ret )
|
|
{
|
|
IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
|
|
|
|
if (!clientSite)
|
|
return E_OUTOFMEMORY;
|
|
|
|
clientSite->IOleClientSite_iface.lpVtbl = &ocst;
|
|
clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
|
|
clientSite->ref = 1;
|
|
clientSite->child.reole = services;
|
|
list_add_head( &services->clientsites, &clientSite->child.entry );
|
|
|
|
*ret = &clientSite->IOleClientSite_iface;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnGetClientSite( IRichEditOle *iface, IOleClientSite **clientsite )
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
|
|
TRACE("(%p)->(%p)\n", services, clientsite);
|
|
|
|
if (!clientsite)
|
|
return E_INVALIDARG;
|
|
|
|
return CreateOleClientSite( services, clientsite );
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnGetClipboardData(IRichEditOle *iface, CHARRANGE *lpchrg,
|
|
DWORD reco, LPDATAOBJECT *lplpdataobj)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
ME_Cursor start;
|
|
int nChars;
|
|
|
|
TRACE("(%p,%p,%ld)\n", services, lpchrg, reco);
|
|
if(!lplpdataobj)
|
|
return E_INVALIDARG;
|
|
if(!lpchrg)
|
|
{
|
|
LONG nFrom, nTo;
|
|
int nStartCur = ME_GetSelectionOfs( services->editor, &nFrom, &nTo );
|
|
start = services->editor->pCursors[nStartCur];
|
|
nChars = nTo - nFrom;
|
|
}
|
|
else
|
|
{
|
|
cursor_from_char_ofs( services->editor, lpchrg->cpMin, &start );
|
|
nChars = lpchrg->cpMax - lpchrg->cpMin;
|
|
}
|
|
return ME_GetDataObject( services->editor, &start, nChars, lplpdataobj );
|
|
}
|
|
|
|
static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *iface)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnGetObject(IRichEditOle *iface, LONG iob,
|
|
REOBJECT *lpreobject, DWORD dwFlags)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
struct re_object *reobj = NULL;
|
|
LONG count = 0;
|
|
|
|
TRACE("(%p)->(%lx, %p, %lx)\n", services, iob, lpreobject, dwFlags);
|
|
|
|
if (!lpreobject || !lpreobject->cbStruct)
|
|
return E_INVALIDARG;
|
|
|
|
if (iob == REO_IOB_USE_CP)
|
|
{
|
|
ME_Cursor cursor;
|
|
|
|
TRACE("character offset: %ld\n", lpreobject->cp);
|
|
cursor_from_char_ofs( services->editor, lpreobject->cp, &cursor );
|
|
if (!cursor.run->reobj)
|
|
return E_INVALIDARG;
|
|
else
|
|
reobj = cursor.run->reobj;
|
|
}
|
|
else if (iob == REO_IOB_SELECTION)
|
|
{
|
|
ME_Cursor *from, *to;
|
|
|
|
ME_GetSelection(services->editor, &from, &to);
|
|
if (!from->run->reobj)
|
|
return E_INVALIDARG;
|
|
else
|
|
reobj = from->run->reobj;
|
|
}
|
|
else
|
|
{
|
|
if (iob < 0 || iob >= IRichEditOle_GetObjectCount( iface ))
|
|
return E_INVALIDARG;
|
|
LIST_FOR_EACH_ENTRY(reobj, &services->editor->reobj_list, struct re_object, entry)
|
|
{
|
|
if (count == iob)
|
|
break;
|
|
count++;
|
|
}
|
|
}
|
|
ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
|
|
lpreobject->cp = run_char_ofs( reobj->run, 0 );
|
|
return S_OK;
|
|
}
|
|
|
|
static LONG WINAPI
|
|
IRichEditOle_fnGetObjectCount( IRichEditOle *iface )
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
TRACE("(%p)\n", services);
|
|
return list_count( &services->editor->reobj_list );
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnHandsOffStorage(IRichEditOle *iface, LONG iob)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnImportDataObject(IRichEditOle *iface, LPDATAOBJECT lpdataobj,
|
|
CLIPFORMAT cf, HGLOBAL hMetaPict)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnInPlaceDeactivate(IRichEditOle *iface)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnInsertObject(IRichEditOle *iface, REOBJECT *reo)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
|
|
TRACE("(%p,%p)\n", services, reo);
|
|
|
|
if (!reo)
|
|
return E_INVALIDARG;
|
|
|
|
if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
|
|
|
|
editor_insert_oleobj(services->editor, reo);
|
|
ME_CommitUndo(services->editor);
|
|
ME_UpdateRepaint(services->editor, FALSE);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *iface, LONG iob,
|
|
LPSTORAGE lpstg)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnSetDvaspect(IRichEditOle *iface, LONG iob, DWORD dvaspect)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *iface,
|
|
LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p %s %s\n", services, lpstrContainerApp, lpstrContainerObj);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI
|
|
IRichEditOle_fnSetLinkAvailable(IRichEditOle *iface, LONG iob, BOOL fAvailable)
|
|
{
|
|
struct text_services *services = impl_from_IRichEditOle( iface );
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
const IRichEditOleVtbl re_ole_vtbl =
|
|
{
|
|
IRichEditOle_fnQueryInterface,
|
|
IRichEditOle_fnAddRef,
|
|
IRichEditOle_fnRelease,
|
|
IRichEditOle_fnGetClientSite,
|
|
IRichEditOle_fnGetObjectCount,
|
|
IRichEditOle_fnGetLinkCount,
|
|
IRichEditOle_fnGetObject,
|
|
IRichEditOle_fnInsertObject,
|
|
IRichEditOle_fnConvertObject,
|
|
IRichEditOle_fnActivateAs,
|
|
IRichEditOle_fnSetHostNames,
|
|
IRichEditOle_fnSetLinkAvailable,
|
|
IRichEditOle_fnSetDvaspect,
|
|
IRichEditOle_fnHandsOffStorage,
|
|
IRichEditOle_fnSaveCompleted,
|
|
IRichEditOle_fnInPlaceDeactivate,
|
|
IRichEditOle_fnContextSensitiveHelp,
|
|
IRichEditOle_fnGetClipboardData,
|
|
IRichEditOle_fnImportDataObject
|
|
};
|
|
|
|
/* ITextRange interface */
|
|
static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
*ppvObj = NULL;
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IDispatch)
|
|
|| IsEqualGUID(riid, &IID_ITextRange))
|
|
{
|
|
*ppvObj = me;
|
|
ITextRange_AddRef(me);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualGUID(riid, &IID_Igetrichole))
|
|
{
|
|
*ppvObj = This->child.reole;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE ("%p ref=%lu\n", This, ref);
|
|
if (ref == 0)
|
|
{
|
|
if (This->child.reole)
|
|
{
|
|
list_remove(&This->child.entry);
|
|
This->child.reole = NULL;
|
|
}
|
|
heap_free(This);
|
|
}
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
TRACE("(%p)->(%p)\n", This, pctinfo);
|
|
*pctinfo = 1;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
|
|
ITypeInfo **ppTInfo)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
|
|
|
|
hr = get_typeinfo(ITextRange_tid, ppTInfo);
|
|
if (SUCCEEDED(hr))
|
|
ITypeInfo_AddRef(*ppTInfo);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
|
|
UINT cNames, LCID lcid, DISPID *rgDispId)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
|
|
rgDispId);
|
|
|
|
hr = get_typeinfo(ITextRange_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
|
|
LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
|
|
VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
|
|
UINT *puArgErr)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
|
|
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
|
|
hr = get_typeinfo(ITextRange_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ME_TextEditor *editor;
|
|
ME_Cursor start, end;
|
|
int length;
|
|
BOOL bEOP;
|
|
|
|
TRACE("(%p)->(%p)\n", This, str);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!str)
|
|
return E_INVALIDARG;
|
|
|
|
/* return early for degenerate range */
|
|
if (This->start == This->end) {
|
|
*str = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
editor = This->child.reole->editor;
|
|
cursor_from_char_ofs( editor, This->start, &start );
|
|
cursor_from_char_ofs( editor, This->end, &end );
|
|
|
|
length = This->end - This->start;
|
|
*str = SysAllocStringLen(NULL, length);
|
|
if (!*str)
|
|
return E_OUTOFMEMORY;
|
|
|
|
bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor));
|
|
ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ME_TextEditor *editor;
|
|
ME_Cursor cursor;
|
|
ME_Style *style;
|
|
int len;
|
|
|
|
TRACE("(%p)->(%s)\n", This, debugstr_w(str));
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
editor = This->child.reole->editor;
|
|
|
|
/* delete only where's something to delete */
|
|
if (This->start != This->end)
|
|
{
|
|
cursor_from_char_ofs( editor, This->start, &cursor );
|
|
ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
|
|
}
|
|
|
|
if (!str || !*str)
|
|
{
|
|
/* will update this range as well */
|
|
textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
|
|
return S_OK;
|
|
}
|
|
|
|
/* it's safer not to rely on stored BSTR length */
|
|
len = lstrlenW(str);
|
|
cursor = editor->pCursors[0];
|
|
cursor_from_char_ofs( editor, This->start, &editor->pCursors[0] );
|
|
style = style_get_insert_style( editor, editor->pCursors );
|
|
ME_InsertTextFromCursor(editor, 0, str, len, style);
|
|
ME_ReleaseStyle(style);
|
|
editor->pCursors[0] = cursor;
|
|
|
|
if (len < This->end - This->start)
|
|
textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
|
|
else
|
|
This->end = len - This->start;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
|
|
{
|
|
WCHAR wch[2];
|
|
|
|
ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) ));
|
|
*pch = wch[0];
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ME_TextEditor *editor;
|
|
ME_Cursor cursor;
|
|
|
|
TRACE("(%p)->(%p)\n", This, pch);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!pch)
|
|
return E_INVALIDARG;
|
|
|
|
editor = This->child.reole->editor;
|
|
cursor_from_char_ofs( editor, This->start, &cursor );
|
|
return range_GetChar(editor, &cursor, pch);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%lx): stub\n", This, ch);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange);
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, ppRange);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!ppRange)
|
|
return E_INVALIDARG;
|
|
|
|
return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, range);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, range);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, start);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!start)
|
|
return E_INVALIDARG;
|
|
|
|
*start = This->start;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT textrange_setstart(const struct text_services *services, LONG value, LONG *start, LONG *end)
|
|
{
|
|
int len;
|
|
|
|
if (value < 0)
|
|
value = 0;
|
|
|
|
if (value == *start)
|
|
return S_FALSE;
|
|
|
|
if (value <= *end) {
|
|
*start = value;
|
|
return S_OK;
|
|
}
|
|
|
|
len = ME_GetTextLength(services->editor);
|
|
*start = *end = value > len ? len : value;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_setstart(This->child.reole, value, &This->start, &This->end);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, end);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!end)
|
|
return E_INVALIDARG;
|
|
|
|
*end = This->end;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT textrange_setend(const struct text_services *services, LONG value, LONG *start, LONG *end)
|
|
{
|
|
int len;
|
|
|
|
if (value == *end)
|
|
return S_FALSE;
|
|
|
|
if (value < *start) {
|
|
*start = *end = max(0, value);
|
|
return S_OK;
|
|
}
|
|
|
|
len = ME_GetTextLength( services->editor );
|
|
*end = value > len ? len + 1 : value;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_setend(This->child.reole, value, &This->start, &This->end);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, font);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!font)
|
|
return E_INVALIDARG;
|
|
|
|
return create_textfont(me, NULL, font);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, font);
|
|
|
|
if (!font)
|
|
return E_INVALIDARG;
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
textrange_set_font(me, font);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, para);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!para)
|
|
return E_INVALIDARG;
|
|
|
|
return create_textpara(me, para);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, para);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, length);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_get_storylength(This->child.reole->editor, length);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!value)
|
|
return E_INVALIDARG;
|
|
|
|
*value = tomUnknownStory;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
|
|
{
|
|
if (*end == *start)
|
|
return S_FALSE;
|
|
|
|
if (bStart == tomEnd)
|
|
*start = *end;
|
|
else
|
|
*end = *start;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld)\n", This, bStart);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return range_Collapse(bStart, &This->start, &This->end);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld %p)\n", This, unit, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_expand(me, unit, delta);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%ld %p): stub\n", This, unit, index);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
|
|
LONG extend)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld): stub\n", This, unit, index, extend);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
|
|
{
|
|
int len = ME_GetTextLength(editor) + 1;
|
|
|
|
*cp1 = max(*cp1, 0);
|
|
*cp2 = max(*cp2, 0);
|
|
*cp1 = min(*cp1, len);
|
|
*cp2 = min(*cp2, len);
|
|
if (*cp1 > *cp2)
|
|
{
|
|
int tmp = *cp1;
|
|
*cp1 = *cp2;
|
|
*cp2 = tmp;
|
|
}
|
|
if (*cp1 == len)
|
|
*cp1 = *cp2 = len - 1;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld %ld)\n", This, anchor, active);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
cp2range(This->child.reole->editor, &anchor, &active);
|
|
if (anchor == This->start && active == This->end)
|
|
return S_FALSE;
|
|
|
|
This->start = anchor;
|
|
This->end = active;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
|
|
{
|
|
LONG from, to, v;
|
|
|
|
if (!ret)
|
|
ret = &v;
|
|
|
|
if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
|
|
*ret = tomFalse;
|
|
}
|
|
else
|
|
*ret = (start >= from && end <= to) ? tomTrue : tomFalse;
|
|
return *ret == tomTrue ? S_OK : S_FALSE;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p %p)\n", This, range, ret);
|
|
|
|
if (ret)
|
|
*ret = tomFalse;
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!range)
|
|
return S_FALSE;
|
|
|
|
return textrange_inrange(This->start, This->end, range, ret);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, ret);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
|
|
{
|
|
LONG from, to, v;
|
|
|
|
if (!ret)
|
|
ret = &v;
|
|
|
|
if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
|
|
*ret = tomFalse;
|
|
}
|
|
else
|
|
*ret = (start == from && end == to) ? tomTrue : tomFalse;
|
|
return *ret == tomTrue ? S_OK : S_FALSE;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p %p)\n", This, range, ret);
|
|
|
|
if (ret)
|
|
*ret = tomFalse;
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!range)
|
|
return S_FALSE;
|
|
|
|
return textrange_isequal(This->start, This->end, range, ret);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)\n", This);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
set_selection(This->child.reole->editor, This->start, This->end);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta)
|
|
{
|
|
HRESULT hr;
|
|
LONG start, end;
|
|
LONG moved;
|
|
|
|
ITextRange_GetStart(range, &start);
|
|
ITextRange_GetEnd(range, &end);
|
|
|
|
switch (unit)
|
|
{
|
|
case tomCharacter:
|
|
{
|
|
moved = 0;
|
|
if (extend == tomMove) {
|
|
if (start != end) {
|
|
ITextRange_SetEnd(range, start);
|
|
moved = -1;
|
|
}
|
|
}
|
|
if (delta)
|
|
*delta = moved;
|
|
hr = moved ? S_OK : S_FALSE;
|
|
break;
|
|
}
|
|
default:
|
|
FIXME("unit %ld is not supported\n", unit);
|
|
return E_NOTIMPL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_startof(me, unit, extend, delta);
|
|
}
|
|
|
|
static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta)
|
|
{
|
|
HRESULT hr;
|
|
LONG old_start, old_end, new_end;
|
|
LONG moved;
|
|
|
|
ITextRange_GetStart(range, &old_start);
|
|
ITextRange_GetEnd(range, &old_end);
|
|
|
|
switch (unit)
|
|
{
|
|
case tomCharacter:
|
|
{
|
|
moved = 0;
|
|
new_end = old_end;
|
|
if (old_end == 0)
|
|
{
|
|
ME_Cursor cursor;
|
|
cursor_from_char_ofs( editor, old_end, &cursor );
|
|
moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE);
|
|
new_end = old_end + moved;
|
|
}
|
|
else if (extend == tomMove && old_start != old_end)
|
|
moved = 1;
|
|
|
|
ITextRange_SetEnd(range, new_end);
|
|
if (extend == tomMove)
|
|
ITextRange_SetStart(range, new_end);
|
|
if (delta)
|
|
*delta = moved;
|
|
hr = moved ? S_OK : S_FALSE;
|
|
break;
|
|
}
|
|
default:
|
|
FIXME("unit %ld is not supported\n", unit);
|
|
return E_NOTIMPL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_endof(me, This->child.reole->editor, unit, extend, delta);
|
|
}
|
|
|
|
static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
|
|
{
|
|
LONG old_start, old_end, new_start, new_end;
|
|
LONG move_by;
|
|
LONG moved;
|
|
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 tomCharacter:
|
|
{
|
|
ME_Cursor cursor;
|
|
|
|
if (count > 0)
|
|
{
|
|
cursor_from_char_ofs( editor, old_end, &cursor );
|
|
move_by = count;
|
|
if (old_start != old_end)
|
|
--move_by;
|
|
}
|
|
else
|
|
{
|
|
cursor_from_char_ofs( editor, old_start, &cursor );
|
|
move_by = count;
|
|
if (old_start != old_end)
|
|
++move_by;
|
|
}
|
|
moved = ME_MoveCursorChars(editor, &cursor, move_by, FALSE);
|
|
if (count > 0)
|
|
{
|
|
new_end = old_end + moved;
|
|
new_start = new_end;
|
|
if (old_start != old_end)
|
|
++moved;
|
|
}
|
|
else
|
|
{
|
|
new_start = old_start + moved;
|
|
new_end = new_start;
|
|
if (old_start != old_end)
|
|
--moved;
|
|
}
|
|
if (delta) *delta = moved;
|
|
break;
|
|
}
|
|
default:
|
|
FIXME("unit %ld is not supported\n", unit);
|
|
return E_NOTIMPL;
|
|
}
|
|
if (moved == 0)
|
|
hr = S_FALSE;
|
|
ITextRange_SetStart(range, new_start);
|
|
ITextRange_SetEnd(range, new_end);
|
|
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_move(me, This->child.reole->editor, unit, count, delta);
|
|
}
|
|
|
|
static HRESULT textrange_movestart(ITextRange *range, ME_TextEditor *editor, 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 tomCharacter:
|
|
{
|
|
ME_Cursor cursor;
|
|
LONG moved;
|
|
|
|
cursor_from_char_ofs( editor, old_start, &cursor );
|
|
moved = ME_MoveCursorChars(editor, &cursor, count, FALSE);
|
|
new_start = old_start + moved;
|
|
new_end = old_end;
|
|
if (new_end < new_start)
|
|
new_end = new_start;
|
|
if (delta)
|
|
*delta = moved;
|
|
break;
|
|
}
|
|
default:
|
|
FIXME("unit %ld is not supported\n", unit);
|
|
return E_NOTIMPL;
|
|
}
|
|
if (new_start == old_start)
|
|
hr = S_FALSE;
|
|
ITextRange_SetStart(range, new_start);
|
|
ITextRange_SetEnd(range, new_end);
|
|
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_movestart(me, This->child.reole->editor, unit, count, delta);
|
|
}
|
|
|
|
static HRESULT textrange_moveend(ITextRange *range, ME_TextEditor *editor, 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 tomCharacter:
|
|
{
|
|
ME_Cursor cursor;
|
|
LONG moved;
|
|
|
|
cursor_from_char_ofs( editor, old_end, &cursor );
|
|
moved = ME_MoveCursorChars(editor, &cursor, count, TRUE);
|
|
new_start = old_start;
|
|
new_end = old_end + moved;
|
|
if (new_end < new_start)
|
|
new_start = new_end;
|
|
if (delta)
|
|
*delta = moved;
|
|
break;
|
|
}
|
|
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 %ld 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);
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_moveend(me, This->child.reole->editor, unit, count, delta);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
|
|
LONG *length)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
|
|
LONG flags, LONG *length)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
|
|
LONG flags, LONG *length)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, count, delta);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT textrange_copy_or_cut( ITextRange *range, ME_TextEditor *editor, BOOL cut, VARIANT *v )
|
|
{
|
|
LONG start, end;
|
|
ME_Cursor cursor;
|
|
IDataObject **data_out = NULL;
|
|
|
|
ITextRange_GetStart( range, &start );
|
|
ITextRange_GetEnd( range, &end );
|
|
if (start == end)
|
|
{
|
|
/* If the range is empty, all text is copied */
|
|
LONG prev_end = end;
|
|
ITextRange_SetEnd( range, MAXLONG );
|
|
start = 0;
|
|
ITextRange_GetEnd( range, &end );
|
|
ITextRange_SetEnd( range, prev_end );
|
|
}
|
|
cursor_from_char_ofs( editor, start, &cursor );
|
|
|
|
if (v && V_VT(v) == (VT_UNKNOWN | VT_BYREF) && V_UNKNOWNREF( v ))
|
|
data_out = (IDataObject **)V_UNKNOWNREF( v );
|
|
|
|
return editor_copy_or_cut( editor, cut, &cursor, end - start, data_out );
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, v);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_copy_or_cut(me, This->child.reole->editor, TRUE, v);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, v);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_copy_or_cut(me, This->child.reole->editor, FALSE, v);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %lx): stub\n", This, debugstr_variant(v), format);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%s %lx %p): stub\n", This, debugstr_variant(v), format, ret);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, ret);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%ld): stub\n", This, type);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%ld %p %p): stub\n", This, type, cx, cy);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
|
|
LONG extend)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld %ld): stub\n", This, x, y, type, extend);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
ME_TextEditor *editor;
|
|
ME_Cursor cursor;
|
|
int x, y, height;
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
editor = This->child.reole->editor;
|
|
|
|
switch (value)
|
|
{
|
|
case tomStart:
|
|
cursor_from_char_ofs( editor, This->start, &cursor );
|
|
cursor_coords( editor, &cursor, &x, &y, &height );
|
|
break;
|
|
case tomEnd:
|
|
cursor_from_char_ofs( editor, This->end, &cursor );
|
|
cursor_coords( editor, &cursor, &x, &y, &height );
|
|
break;
|
|
default:
|
|
FIXME("bStart value %ld not handled\n", value);
|
|
return E_NOTIMPL;
|
|
}
|
|
scroll_abs( editor, x, y, TRUE );
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
|
|
{
|
|
ITextRangeImpl *This = impl_from_ITextRange(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, ppv);
|
|
|
|
if (!This->child.reole)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const ITextRangeVtbl trvt = {
|
|
ITextRange_fnQueryInterface,
|
|
ITextRange_fnAddRef,
|
|
ITextRange_fnRelease,
|
|
ITextRange_fnGetTypeInfoCount,
|
|
ITextRange_fnGetTypeInfo,
|
|
ITextRange_fnGetIDsOfNames,
|
|
ITextRange_fnInvoke,
|
|
ITextRange_fnGetText,
|
|
ITextRange_fnSetText,
|
|
ITextRange_fnGetChar,
|
|
ITextRange_fnSetChar,
|
|
ITextRange_fnGetDuplicate,
|
|
ITextRange_fnGetFormattedText,
|
|
ITextRange_fnSetFormattedText,
|
|
ITextRange_fnGetStart,
|
|
ITextRange_fnSetStart,
|
|
ITextRange_fnGetEnd,
|
|
ITextRange_fnSetEnd,
|
|
ITextRange_fnGetFont,
|
|
ITextRange_fnSetFont,
|
|
ITextRange_fnGetPara,
|
|
ITextRange_fnSetPara,
|
|
ITextRange_fnGetStoryLength,
|
|
ITextRange_fnGetStoryType,
|
|
ITextRange_fnCollapse,
|
|
ITextRange_fnExpand,
|
|
ITextRange_fnGetIndex,
|
|
ITextRange_fnSetIndex,
|
|
ITextRange_fnSetRange,
|
|
ITextRange_fnInRange,
|
|
ITextRange_fnInStory,
|
|
ITextRange_fnIsEqual,
|
|
ITextRange_fnSelect,
|
|
ITextRange_fnStartOf,
|
|
ITextRange_fnEndOf,
|
|
ITextRange_fnMove,
|
|
ITextRange_fnMoveStart,
|
|
ITextRange_fnMoveEnd,
|
|
ITextRange_fnMoveWhile,
|
|
ITextRange_fnMoveStartWhile,
|
|
ITextRange_fnMoveEndWhile,
|
|
ITextRange_fnMoveUntil,
|
|
ITextRange_fnMoveStartUntil,
|
|
ITextRange_fnMoveEndUntil,
|
|
ITextRange_fnFindText,
|
|
ITextRange_fnFindTextStart,
|
|
ITextRange_fnFindTextEnd,
|
|
ITextRange_fnDelete,
|
|
ITextRange_fnCut,
|
|
ITextRange_fnCopy,
|
|
ITextRange_fnPaste,
|
|
ITextRange_fnCanPaste,
|
|
ITextRange_fnCanEdit,
|
|
ITextRange_fnChangeCase,
|
|
ITextRange_fnGetPoint,
|
|
ITextRange_fnSetPoint,
|
|
ITextRange_fnScrollIntoView,
|
|
ITextRange_fnGetEmbeddedObject
|
|
};
|
|
|
|
/* ITextFont */
|
|
static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
|
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
|
|
|
if (IsEqualIID(riid, &IID_ITextFont) ||
|
|
IsEqualIID(riid, &IID_IDispatch) ||
|
|
IsEqualIID(riid, &IID_IUnknown))
|
|
{
|
|
*ppv = iface;
|
|
ITextFont_AddRef(iface);
|
|
return S_OK;
|
|
}
|
|
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
ULONG ref = InterlockedIncrement(&This->ref);
|
|
TRACE("(%p)->(%lu)\n", This, ref);
|
|
return ref;
|
|
}
|
|
|
|
static ULONG WINAPI TextFont_Release(ITextFont *iface)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("(%p)->(%lu)\n", This, ref);
|
|
|
|
if (!ref)
|
|
{
|
|
if (This->range)
|
|
ITextRange_Release(This->range);
|
|
SysFreeString(This->props[FONT_NAME].str);
|
|
heap_free(This);
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, pctinfo);
|
|
*pctinfo = 1;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
|
|
ITypeInfo **ppTInfo)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
|
|
|
|
hr = get_typeinfo(ITextFont_tid, ppTInfo);
|
|
if (SUCCEEDED(hr))
|
|
ITypeInfo_AddRef(*ppTInfo);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
|
|
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid),
|
|
rgszNames, cNames, lcid, rgDispId);
|
|
|
|
hr = get_typeinfo(ITextFont_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_Invoke(
|
|
ITextFont *iface,
|
|
DISPID dispIdMember,
|
|
REFIID riid,
|
|
LCID lcid,
|
|
WORD wFlags,
|
|
DISPPARAMS *pDispParams,
|
|
VARIANT *pVarResult,
|
|
EXCEPINFO *pExcepInfo,
|
|
UINT *puArgErr)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
|
|
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
|
|
hr = get_typeinfo(ITextFont_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
|
|
TRACE("(%p)->(%p)\n", This, ret);
|
|
|
|
if (!ret)
|
|
return E_INVALIDARG;
|
|
|
|
*ret = NULL;
|
|
if (This->range && !get_range_reole(This->range))
|
|
return CO_E_RELEASED;
|
|
|
|
return create_textfont(NULL, This, ret);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
FIXME("(%p)->(%p): stub\n", This, pFont);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
FIXME("(%p)->(%p): stub\n", This, ret);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
FIXME("(%p)->(%p %p): stub\n", This, font, ret);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static void textfont_reset_to_default(ITextFontImpl *font)
|
|
{
|
|
enum textfont_prop_id id;
|
|
|
|
for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
|
|
switch (id)
|
|
{
|
|
case FONT_ALLCAPS:
|
|
case FONT_ANIMATION:
|
|
case FONT_BOLD:
|
|
case FONT_EMBOSS:
|
|
case FONT_HIDDEN:
|
|
case FONT_ENGRAVE:
|
|
case FONT_ITALIC:
|
|
case FONT_OUTLINE:
|
|
case FONT_PROTECTED:
|
|
case FONT_SHADOW:
|
|
case FONT_SMALLCAPS:
|
|
case FONT_STRIKETHROUGH:
|
|
case FONT_SUBSCRIPT:
|
|
case FONT_SUPERSCRIPT:
|
|
case FONT_UNDERLINE:
|
|
font->props[id].l = tomFalse;
|
|
break;
|
|
case FONT_BACKCOLOR:
|
|
case FONT_FORECOLOR:
|
|
font->props[id].l = tomAutoColor;
|
|
break;
|
|
case FONT_KERNING:
|
|
case FONT_POSITION:
|
|
case FONT_SIZE:
|
|
case FONT_SPACING:
|
|
font->props[id].f = 0.0;
|
|
break;
|
|
case FONT_LANGID:
|
|
font->props[id].l = GetSystemDefaultLCID();
|
|
break;
|
|
case FONT_NAME: {
|
|
SysFreeString(font->props[id].str);
|
|
font->props[id].str = SysAllocString(L"System");
|
|
break;
|
|
}
|
|
case FONT_WEIGHT:
|
|
font->props[id].l = FW_NORMAL;
|
|
break;
|
|
default:
|
|
FIXME("font property %d not handled\n", id);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void textfont_reset_to_undefined(ITextFontImpl *font)
|
|
{
|
|
enum textfont_prop_id id;
|
|
|
|
for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
|
|
switch (id)
|
|
{
|
|
case FONT_ALLCAPS:
|
|
case FONT_ANIMATION:
|
|
case FONT_BOLD:
|
|
case FONT_EMBOSS:
|
|
case FONT_HIDDEN:
|
|
case FONT_ENGRAVE:
|
|
case FONT_ITALIC:
|
|
case FONT_OUTLINE:
|
|
case FONT_PROTECTED:
|
|
case FONT_SHADOW:
|
|
case FONT_SMALLCAPS:
|
|
case FONT_STRIKETHROUGH:
|
|
case FONT_SUBSCRIPT:
|
|
case FONT_SUPERSCRIPT:
|
|
case FONT_UNDERLINE:
|
|
case FONT_BACKCOLOR:
|
|
case FONT_FORECOLOR:
|
|
case FONT_LANGID:
|
|
case FONT_WEIGHT:
|
|
font->props[id].l = tomUndefined;
|
|
break;
|
|
case FONT_KERNING:
|
|
case FONT_POSITION:
|
|
case FONT_SIZE:
|
|
case FONT_SPACING:
|
|
font->props[id].f = tomUndefined;
|
|
break;
|
|
case FONT_NAME:
|
|
break;
|
|
default:
|
|
FIXME("font property %d not handled\n", id);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void textfont_apply_range_props(ITextFontImpl *font)
|
|
{
|
|
enum textfont_prop_id propid;
|
|
for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
|
|
set_textfont_prop(font, propid, &font->props[propid]);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
/* If font is attached to a range, released or not, we can't
|
|
reset to undefined */
|
|
if (This->range) {
|
|
if (!get_range_reole(This->range))
|
|
return CO_E_RELEASED;
|
|
|
|
switch (value)
|
|
{
|
|
case tomUndefined:
|
|
return E_INVALIDARG;
|
|
case tomCacheParms:
|
|
textfont_cache_range_props(This);
|
|
This->get_cache_enabled = TRUE;
|
|
break;
|
|
case tomTrackParms:
|
|
This->get_cache_enabled = FALSE;
|
|
break;
|
|
case tomApplyLater:
|
|
This->set_cache_enabled = TRUE;
|
|
break;
|
|
case tomApplyNow:
|
|
This->set_cache_enabled = FALSE;
|
|
textfont_apply_range_props(This);
|
|
break;
|
|
case tomUsePoints:
|
|
case tomUseTwips:
|
|
return E_INVALIDARG;
|
|
default:
|
|
FIXME("reset mode %ld not supported\n", value);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
else {
|
|
switch (value)
|
|
{
|
|
/* reset to global defaults */
|
|
case tomDefault:
|
|
textfont_reset_to_default(This);
|
|
return S_OK;
|
|
/* all properties are set to tomUndefined, font name is retained */
|
|
case tomUndefined:
|
|
textfont_reset_to_undefined(This);
|
|
return S_OK;
|
|
case tomApplyNow:
|
|
case tomApplyLater:
|
|
case tomTrackParms:
|
|
case tomCacheParms:
|
|
return S_OK;
|
|
case tomUsePoints:
|
|
case tomUseTwips:
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
FIXME("reset mode %ld not supported\n", value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
FIXME("(%p)->(%p): stub\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
FIXME("(%p)->(%ld): stub\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_ALLCAPS, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_ALLCAPS, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_ANIMATION, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
if (value < tomNoAnimation || value > tomAnimationMax)
|
|
return E_INVALIDARG;
|
|
|
|
return set_textfont_propl(This, FONT_ANIMATION, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_BACKCOLOR, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propl(This, FONT_BACKCOLOR, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_BOLD, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_BOLD, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_EMBOSS, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_EMBOSS, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_FORECOLOR, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propl(This, FONT_FORECOLOR, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_HIDDEN, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_HIDDEN, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_ENGRAVE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_ENGRAVE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_ITALIC, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_ITALIC, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propf(This, FONT_KERNING, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%.2f)\n", This, value);
|
|
return set_textfont_propf(This, FONT_KERNING, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_LANGID, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propl(This, FONT_LANGID, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
|
|
if (!value)
|
|
return E_INVALIDARG;
|
|
|
|
*value = NULL;
|
|
|
|
if (!This->range) {
|
|
if (This->props[FONT_NAME].str)
|
|
*value = SysAllocString(This->props[FONT_NAME].str);
|
|
else
|
|
*value = SysAllocStringLen(NULL, 0);
|
|
return *value ? S_OK : E_OUTOFMEMORY;
|
|
}
|
|
|
|
return textfont_getname_from_range(This->range, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
textfont_prop_val v;
|
|
|
|
TRACE("(%p)->(%s)\n", This, debugstr_w(value));
|
|
|
|
v.str = value;
|
|
return set_textfont_prop(This, FONT_NAME, &v);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_OUTLINE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_OUTLINE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propf(This, FONT_POSITION, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%.2f)\n", This, value);
|
|
return set_textfont_propf(This, FONT_POSITION, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_PROTECTED, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_PROTECTED, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_SHADOW, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_SHADOW, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propf(This, FONT_SIZE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%.2f)\n", This, value);
|
|
return set_textfont_propf(This, FONT_SIZE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_SMALLCAPS, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_SMALLCAPS, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propf(This, FONT_SPACING, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%.2f)\n", This, value);
|
|
return set_textfont_propf(This, FONT_SPACING, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_SUBSCRIPT, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_SUBSCRIPT, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_UNDERLINE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propd(This, FONT_UNDERLINE, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
return get_textfont_propl(This, FONT_WEIGHT, value);
|
|
}
|
|
|
|
static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
|
|
{
|
|
ITextFontImpl *This = impl_from_ITextFont(iface);
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
return set_textfont_propl(This, FONT_WEIGHT, value);
|
|
}
|
|
|
|
static ITextFontVtbl textfontvtbl = {
|
|
TextFont_QueryInterface,
|
|
TextFont_AddRef,
|
|
TextFont_Release,
|
|
TextFont_GetTypeInfoCount,
|
|
TextFont_GetTypeInfo,
|
|
TextFont_GetIDsOfNames,
|
|
TextFont_Invoke,
|
|
TextFont_GetDuplicate,
|
|
TextFont_SetDuplicate,
|
|
TextFont_CanChange,
|
|
TextFont_IsEqual,
|
|
TextFont_Reset,
|
|
TextFont_GetStyle,
|
|
TextFont_SetStyle,
|
|
TextFont_GetAllCaps,
|
|
TextFont_SetAllCaps,
|
|
TextFont_GetAnimation,
|
|
TextFont_SetAnimation,
|
|
TextFont_GetBackColor,
|
|
TextFont_SetBackColor,
|
|
TextFont_GetBold,
|
|
TextFont_SetBold,
|
|
TextFont_GetEmboss,
|
|
TextFont_SetEmboss,
|
|
TextFont_GetForeColor,
|
|
TextFont_SetForeColor,
|
|
TextFont_GetHidden,
|
|
TextFont_SetHidden,
|
|
TextFont_GetEngrave,
|
|
TextFont_SetEngrave,
|
|
TextFont_GetItalic,
|
|
TextFont_SetItalic,
|
|
TextFont_GetKerning,
|
|
TextFont_SetKerning,
|
|
TextFont_GetLanguageID,
|
|
TextFont_SetLanguageID,
|
|
TextFont_GetName,
|
|
TextFont_SetName,
|
|
TextFont_GetOutline,
|
|
TextFont_SetOutline,
|
|
TextFont_GetPosition,
|
|
TextFont_SetPosition,
|
|
TextFont_GetProtected,
|
|
TextFont_SetProtected,
|
|
TextFont_GetShadow,
|
|
TextFont_SetShadow,
|
|
TextFont_GetSize,
|
|
TextFont_SetSize,
|
|
TextFont_GetSmallCaps,
|
|
TextFont_SetSmallCaps,
|
|
TextFont_GetSpacing,
|
|
TextFont_SetSpacing,
|
|
TextFont_GetStrikeThrough,
|
|
TextFont_SetStrikeThrough,
|
|
TextFont_GetSubscript,
|
|
TextFont_SetSubscript,
|
|
TextFont_GetSuperscript,
|
|
TextFont_SetSuperscript,
|
|
TextFont_GetUnderline,
|
|
TextFont_SetUnderline,
|
|
TextFont_GetWeight,
|
|
TextFont_SetWeight
|
|
};
|
|
|
|
static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
|
|
{
|
|
ITextFontImpl *font;
|
|
|
|
*ret = NULL;
|
|
font = heap_alloc(sizeof(*font));
|
|
if (!font)
|
|
return E_OUTOFMEMORY;
|
|
|
|
font->ITextFont_iface.lpVtbl = &textfontvtbl;
|
|
font->ref = 1;
|
|
|
|
if (src) {
|
|
font->range = NULL;
|
|
font->get_cache_enabled = TRUE;
|
|
font->set_cache_enabled = TRUE;
|
|
memcpy(&font->props, &src->props, sizeof(font->props));
|
|
if (font->props[FONT_NAME].str)
|
|
font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
|
|
}
|
|
else {
|
|
font->range = range;
|
|
ITextRange_AddRef(range);
|
|
|
|
/* cache current properties */
|
|
font->get_cache_enabled = FALSE;
|
|
font->set_cache_enabled = FALSE;
|
|
textfont_cache_range_props(font);
|
|
}
|
|
|
|
*ret = &font->ITextFont_iface;
|
|
return S_OK;
|
|
}
|
|
|
|
/* ITextPara */
|
|
static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
|
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
|
|
|
if (IsEqualIID(riid, &IID_ITextPara) ||
|
|
IsEqualIID(riid, &IID_IDispatch) ||
|
|
IsEqualIID(riid, &IID_IUnknown))
|
|
{
|
|
*ppv = iface;
|
|
ITextPara_AddRef(iface);
|
|
return S_OK;
|
|
}
|
|
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
ULONG ref = InterlockedIncrement(&This->ref);
|
|
TRACE("(%p)->(%lu)\n", This, ref);
|
|
return ref;
|
|
}
|
|
|
|
static ULONG WINAPI TextPara_Release(ITextPara *iface)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("(%p)->(%lu)\n", This, ref);
|
|
|
|
if (!ref)
|
|
{
|
|
ITextRange_Release(This->range);
|
|
heap_free(This);
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
TRACE("(%p)->(%p)\n", This, pctinfo);
|
|
*pctinfo = 1;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
|
|
ITypeInfo **ppTInfo)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
|
|
|
|
hr = get_typeinfo(ITextPara_tid, ppTInfo);
|
|
if (SUCCEEDED(hr))
|
|
ITypeInfo_AddRef(*ppTInfo);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
|
|
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames,
|
|
cNames, lcid, rgDispId);
|
|
|
|
hr = get_typeinfo(ITextPara_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_Invoke(
|
|
ITextPara *iface,
|
|
DISPID dispIdMember,
|
|
REFIID riid,
|
|
LCID lcid,
|
|
WORD wFlags,
|
|
DISPPARAMS *pDispParams,
|
|
VARIANT *pVarResult,
|
|
EXCEPINFO *pExcepInfo,
|
|
UINT *puArgErr)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember,
|
|
debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
|
|
pExcepInfo, puArgErr);
|
|
|
|
hr = get_typeinfo(ITextPara_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, ret);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, para);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, ret);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p %p)\n", This, para, ret);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld %.2f)\n", This, LineSpacingRule, LineSpacing);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%p)\n", This, value);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f %ld %ld)\n", This, tbPos, tbAlign, tbLeader);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)\n", This);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%.2f)\n", This, pos);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
|
|
{
|
|
ITextParaImpl *This = impl_from_ITextPara(iface);
|
|
FIXME("(%p)->(%ld %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static ITextParaVtbl textparavtbl = {
|
|
TextPara_QueryInterface,
|
|
TextPara_AddRef,
|
|
TextPara_Release,
|
|
TextPara_GetTypeInfoCount,
|
|
TextPara_GetTypeInfo,
|
|
TextPara_GetIDsOfNames,
|
|
TextPara_Invoke,
|
|
TextPara_GetDuplicate,
|
|
TextPara_SetDuplicate,
|
|
TextPara_CanChange,
|
|
TextPara_IsEqual,
|
|
TextPara_Reset,
|
|
TextPara_GetStyle,
|
|
TextPara_SetStyle,
|
|
TextPara_GetAlignment,
|
|
TextPara_SetAlignment,
|
|
TextPara_GetHyphenation,
|
|
TextPara_SetHyphenation,
|
|
TextPara_GetFirstLineIndent,
|
|
TextPara_GetKeepTogether,
|
|
TextPara_SetKeepTogether,
|
|
TextPara_GetKeepWithNext,
|
|
TextPara_SetKeepWithNext,
|
|
TextPara_GetLeftIndent,
|
|
TextPara_GetLineSpacing,
|
|
TextPara_GetLineSpacingRule,
|
|
TextPara_GetListAlignment,
|
|
TextPara_SetListAlignment,
|
|
TextPara_GetListLevelIndex,
|
|
TextPara_SetListLevelIndex,
|
|
TextPara_GetListStart,
|
|
TextPara_SetListStart,
|
|
TextPara_GetListTab,
|
|
TextPara_SetListTab,
|
|
TextPara_GetListType,
|
|
TextPara_SetListType,
|
|
TextPara_GetNoLineNumber,
|
|
TextPara_SetNoLineNumber,
|
|
TextPara_GetPageBreakBefore,
|
|
TextPara_SetPageBreakBefore,
|
|
TextPara_GetRightIndent,
|
|
TextPara_SetRightIndent,
|
|
TextPara_SetIndents,
|
|
TextPara_SetLineSpacing,
|
|
TextPara_GetSpaceAfter,
|
|
TextPara_SetSpaceAfter,
|
|
TextPara_GetSpaceBefore,
|
|
TextPara_SetSpaceBefore,
|
|
TextPara_GetWidowControl,
|
|
TextPara_SetWidowControl,
|
|
TextPara_GetTabCount,
|
|
TextPara_AddTab,
|
|
TextPara_ClearAllTabs,
|
|
TextPara_DeleteTab,
|
|
TextPara_GetTab
|
|
};
|
|
|
|
static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
|
|
{
|
|
ITextParaImpl *para;
|
|
|
|
*ret = NULL;
|
|
para = heap_alloc(sizeof(*para));
|
|
if (!para)
|
|
return E_OUTOFMEMORY;
|
|
|
|
para->ITextPara_iface.lpVtbl = &textparavtbl;
|
|
para->ref = 1;
|
|
para->range = range;
|
|
ITextRange_AddRef(range);
|
|
|
|
*ret = ¶->ITextPara_iface;
|
|
return S_OK;
|
|
}
|
|
|
|
/* ITextDocument */
|
|
static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid,
|
|
void **ppvObject)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
return IUnknown_QueryInterface( services->outer_unk, riid, ppvObject );
|
|
}
|
|
|
|
static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
return IUnknown_AddRef( services->outer_unk );
|
|
}
|
|
|
|
static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
return IUnknown_Release( services->outer_unk );
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface,
|
|
UINT *pctinfo)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
TRACE("(%p)->(%p)\n", services, pctinfo);
|
|
*pctinfo = 1;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid,
|
|
ITypeInfo **ppTInfo)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%u,%ld,%p)\n", services, iTInfo, lcid, ppTInfo);
|
|
|
|
hr = get_typeinfo(ITextDocument_tid, ppTInfo);
|
|
if (SUCCEEDED(hr))
|
|
ITypeInfo_AddRef(*ppTInfo);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface, REFIID riid,
|
|
LPOLESTR *rgszNames, UINT cNames,
|
|
LCID lcid, DISPID *rgDispId)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", services, debugstr_guid(riid),
|
|
rgszNames, cNames, lcid, rgDispId);
|
|
|
|
hr = get_typeinfo(ITextDocument_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPID dispIdMember,
|
|
REFIID riid, LCID lcid, WORD wFlags,
|
|
DISPPARAMS *pDispParams, VARIANT *pVarResult,
|
|
EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", services, dispIdMember,
|
|
debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
|
|
pExcepInfo, puArgErr);
|
|
|
|
hr = get_typeinfo(ITextDocument_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
TRACE("(%p)->(%p)\n", iface, selection);
|
|
|
|
if (!selection)
|
|
return E_INVALIDARG;
|
|
|
|
if (!services->text_selection)
|
|
{
|
|
services->text_selection = text_selection_create( services );
|
|
if (!services->text_selection)
|
|
{
|
|
*selection = NULL;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
*selection = &services->text_selection->ITextSelection_iface;
|
|
ITextSelection_AddRef(*selection);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface,
|
|
ITextStoryRanges **ppStories)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar,
|
|
LONG Flags, LONG CodePage)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar,
|
|
LONG Flags, LONG CodePage)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange)
|
|
{
|
|
ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
|
|
|
|
if (!txtRge)
|
|
return E_OUTOFMEMORY;
|
|
txtRge->ITextRange_iface.lpVtbl = &trvt;
|
|
txtRge->ref = 1;
|
|
txtRge->child.reole = services;
|
|
txtRge->start = start;
|
|
txtRge->end = end;
|
|
list_add_head( &services->rangelist, &txtRge->child.entry );
|
|
*ppRange = &txtRge->ITextRange_iface;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2,
|
|
ITextRange **ppRange)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
TRACE("%p %p %ld %ld\n", services, ppRange, cp1, cp2);
|
|
if (!ppRange)
|
|
return E_INVALIDARG;
|
|
|
|
cp2range(services->editor, &cp1, &cp2);
|
|
return CreateITextRange(services, cp1, cp2, ppRange);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y,
|
|
ITextRange **ppRange)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
FIXME("stub %p\n", services);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/* ITextDocument2Old methods */
|
|
static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, filter);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld, 0x%lx): stub\n", services, index, cr);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld, %p): stub\n", services, index, cr);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, type);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld): stub\n", services, type);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, context);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld): stub\n", services, context);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *iface, LONG cp, LONG charrep,
|
|
LONG options, LONG current_charrep, LONG current_fontsize,
|
|
BSTR *bstr, LONG *pitch_family, LONG *new_fontsize)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld, %ld, %ld, %ld, %ld, %p, %p, %p): stub\n", services, cp, charrep, options, current_charrep,
|
|
current_fontsize, bstr, pitch_family, new_fontsize);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, mode);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(0x%lx): stub\n", services, mode);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top,
|
|
LONG *right, LONG *bottom)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld, %p, %p, %p, %p): stub\n", services, type, left, top, right, bottom);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, selection);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, hwnd);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%p): stub\n", services, flags);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p): stub\n", services);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld, %p): stub\n", services, cch, exceed);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(0x%lx): stub\n", services, mode);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p): stub\n", services);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(0x%lx): stub\n", services, mode);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify)
|
|
{
|
|
struct text_services *services = impl_from_ITextDocument2Old(iface);
|
|
|
|
FIXME("(%p)->(%ld): stub\n", services, notify);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
const ITextDocument2OldVtbl text_doc2old_vtbl =
|
|
{
|
|
ITextDocument2Old_fnQueryInterface,
|
|
ITextDocument2Old_fnAddRef,
|
|
ITextDocument2Old_fnRelease,
|
|
ITextDocument2Old_fnGetTypeInfoCount,
|
|
ITextDocument2Old_fnGetTypeInfo,
|
|
ITextDocument2Old_fnGetIDsOfNames,
|
|
ITextDocument2Old_fnInvoke,
|
|
ITextDocument2Old_fnGetName,
|
|
ITextDocument2Old_fnGetSelection,
|
|
ITextDocument2Old_fnGetStoryCount,
|
|
ITextDocument2Old_fnGetStoryRanges,
|
|
ITextDocument2Old_fnGetSaved,
|
|
ITextDocument2Old_fnSetSaved,
|
|
ITextDocument2Old_fnGetDefaultTabStop,
|
|
ITextDocument2Old_fnSetDefaultTabStop,
|
|
ITextDocument2Old_fnNew,
|
|
ITextDocument2Old_fnOpen,
|
|
ITextDocument2Old_fnSave,
|
|
ITextDocument2Old_fnFreeze,
|
|
ITextDocument2Old_fnUnfreeze,
|
|
ITextDocument2Old_fnBeginEditCollection,
|
|
ITextDocument2Old_fnEndEditCollection,
|
|
ITextDocument2Old_fnUndo,
|
|
ITextDocument2Old_fnRedo,
|
|
ITextDocument2Old_fnRange,
|
|
ITextDocument2Old_fnRangeFromPoint,
|
|
/* ITextDocument2Old methods */
|
|
ITextDocument2Old_fnAttachMsgFilter,
|
|
ITextDocument2Old_fnSetEffectColor,
|
|
ITextDocument2Old_fnGetEffectColor,
|
|
ITextDocument2Old_fnGetCaretType,
|
|
ITextDocument2Old_fnSetCaretType,
|
|
ITextDocument2Old_fnGetImmContext,
|
|
ITextDocument2Old_fnReleaseImmContext,
|
|
ITextDocument2Old_fnGetPreferredFont,
|
|
ITextDocument2Old_fnGetNotificationMode,
|
|
ITextDocument2Old_fnSetNotificationMode,
|
|
ITextDocument2Old_fnGetClientRect,
|
|
ITextDocument2Old_fnGetSelectionEx,
|
|
ITextDocument2Old_fnGetWindow,
|
|
ITextDocument2Old_fnGetFEFlags,
|
|
ITextDocument2Old_fnUpdateWindow,
|
|
ITextDocument2Old_fnCheckTextLimit,
|
|
ITextDocument2Old_fnIMEInProgress,
|
|
ITextDocument2Old_fnSysBeep,
|
|
ITextDocument2Old_fnUpdate,
|
|
ITextDocument2Old_fnNotify
|
|
};
|
|
|
|
/* ITextSelection */
|
|
static HRESULT WINAPI ITextSelection_fnQueryInterface(
|
|
ITextSelection *me,
|
|
REFIID riid,
|
|
void **ppvObj)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
*ppvObj = NULL;
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IDispatch)
|
|
|| IsEqualGUID(riid, &IID_ITextRange)
|
|
|| IsEqualGUID(riid, &IID_ITextSelection))
|
|
{
|
|
*ppvObj = me;
|
|
ITextSelection_AddRef(me);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualGUID(riid, &IID_Igetrichole))
|
|
{
|
|
*ppvObj = This->services;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
if (ref == 0)
|
|
heap_free(This);
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
TRACE("(%p)->(%p)\n", This, pctinfo);
|
|
*pctinfo = 1;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
|
|
ITypeInfo **ppTInfo)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
|
|
|
|
hr = get_typeinfo(ITextSelection_tid, ppTInfo);
|
|
if (SUCCEEDED(hr))
|
|
ITypeInfo_AddRef(*ppTInfo);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
|
|
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
|
|
rgDispId);
|
|
|
|
hr = get_typeinfo(ITextSelection_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnInvoke(
|
|
ITextSelection *me,
|
|
DISPID dispIdMember,
|
|
REFIID riid,
|
|
LCID lcid,
|
|
WORD wFlags,
|
|
DISPPARAMS *pDispParams,
|
|
VARIANT *pVarResult,
|
|
EXCEPINFO *pExcepInfo,
|
|
UINT *puArgErr)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITypeInfo *ti;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
|
|
wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
|
|
hr = get_typeinfo(ITextSelection_tid, &ti);
|
|
if (SUCCEEDED(hr))
|
|
hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
return hr;
|
|
}
|
|
|
|
/*** ITextRange methods ***/
|
|
static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ME_Cursor *start = NULL, *end = NULL;
|
|
int nChars, endOfs;
|
|
BOOL bEOP;
|
|
|
|
TRACE("(%p)->(%p)\n", This, pbstr);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!pbstr)
|
|
return E_INVALIDARG;
|
|
|
|
ME_GetSelection(This->services->editor, &start, &end);
|
|
endOfs = ME_GetCursorOfs(end);
|
|
nChars = endOfs - ME_GetCursorOfs(start);
|
|
if (!nChars)
|
|
{
|
|
*pbstr = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
*pbstr = SysAllocStringLen(NULL, nChars);
|
|
if (!*pbstr)
|
|
return E_OUTOFMEMORY;
|
|
|
|
bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->services->editor));
|
|
ME_GetTextW(This->services->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
|
|
TRACE("%s\n", wine_dbgstr_w(*pbstr));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ME_TextEditor *editor;
|
|
int len;
|
|
LONG to, from;
|
|
|
|
TRACE("(%p)->(%s)\n", This, debugstr_w(str));
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
editor = This->services->editor;
|
|
len = lstrlenW(str);
|
|
ME_GetSelectionOfs(editor, &from, &to);
|
|
ME_ReplaceSel(editor, FALSE, str, len);
|
|
|
|
if (len < to - from)
|
|
textranges_update_ranges(This->services, from, len, RANGE_UPDATE_DELETE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ME_Cursor *start = NULL, *end = NULL;
|
|
|
|
TRACE("(%p)->(%p)\n", This, pch);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!pch)
|
|
return E_INVALIDARG;
|
|
|
|
ME_GetSelection(This->services->editor, &start, &end);
|
|
return range_GetChar(This->services->editor, start, pch);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%lx): stub\n", This, ch);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
LONG start, end;
|
|
|
|
TRACE("(%p)->(%p)\n", This, range);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!range)
|
|
return E_INVALIDARG;
|
|
|
|
ITextSelection_GetStart(me, &start);
|
|
ITextSelection_GetEnd(me, &end);
|
|
return CreateITextRange(This->services, start, end, range);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, range);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, range);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
LONG lim;
|
|
|
|
TRACE("(%p)->(%p)\n", This, pcpFirst);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!pcpFirst)
|
|
return E_INVALIDARG;
|
|
ME_GetSelectionOfs(This->services->editor, pcpFirst, &lim);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
LONG start, end;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ME_GetSelectionOfs(This->services->editor, &start, &end);
|
|
hr = textrange_setstart(This->services, value, &start, &end);
|
|
if (hr == S_OK)
|
|
set_selection(This->services->editor, start, end);
|
|
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
LONG first;
|
|
|
|
TRACE("(%p)->(%p)\n", This, pcpLim);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!pcpLim)
|
|
return E_INVALIDARG;
|
|
ME_GetSelectionOfs(This->services->editor, &first, pcpLim);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
LONG start, end;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld)\n", This, value);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ME_GetSelectionOfs(This->services->editor, &start, &end);
|
|
hr = textrange_setend(This->services, value, &start, &end);
|
|
if (hr == S_OK)
|
|
set_selection(This->services->editor, start, end);
|
|
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%p)\n", This, font);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!font)
|
|
return E_INVALIDARG;
|
|
|
|
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)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
|
|
TRACE("(%p)->(%p)\n", This, font);
|
|
|
|
if (!font)
|
|
return E_INVALIDARG;
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
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)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%p)\n", This, para);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!para)
|
|
return E_INVALIDARG;
|
|
|
|
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)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, para);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, length);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return textrange_get_storylength(This->services->editor, length);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
TRACE("(%p)->(%p)\n", This, value);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!value)
|
|
return E_INVALIDARG;
|
|
|
|
*value = tomUnknownStory;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
LONG start, end;
|
|
HRESULT hres;
|
|
|
|
TRACE("(%p)->(%ld)\n", This, bStart);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ME_GetSelectionOfs(This->services->editor, &start, &end);
|
|
hres = range_Collapse(bStart, &start, &end);
|
|
if (SUCCEEDED(hres))
|
|
set_selection(This->services->editor, start, end);
|
|
return hres;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld %p)\n", This, unit, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
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)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %p): stub\n", This, unit, index);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
|
|
LONG extend)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld): stub\n", This, unit, index, extend);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld): stub\n", This, anchor, active);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextSelection *selection = NULL;
|
|
LONG start, end;
|
|
|
|
TRACE("(%p)->(%p %p)\n", This, range, ret);
|
|
|
|
if (ret)
|
|
*ret = tomFalse;
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!range)
|
|
return S_FALSE;
|
|
|
|
ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
|
|
if (!selection)
|
|
return S_FALSE;
|
|
ITextSelection_Release(selection);
|
|
|
|
ITextSelection_GetStart(me, &start);
|
|
ITextSelection_GetEnd(me, &end);
|
|
return textrange_inrange(start, end, range, ret);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p %p): stub\n", This, range, ret);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextSelection *selection = NULL;
|
|
LONG start, end;
|
|
|
|
TRACE("(%p)->(%p %p)\n", This, range, ret);
|
|
|
|
if (ret)
|
|
*ret = tomFalse;
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
if (!range)
|
|
return S_FALSE;
|
|
|
|
ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
|
|
if (!selection)
|
|
return S_FALSE;
|
|
ITextSelection_Release(selection);
|
|
|
|
ITextSelection_GetStart(me, &start);
|
|
ITextSelection_GetEnd(me, &end);
|
|
return textrange_isequal(start, end, range, ret);
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
TRACE("(%p)\n", This);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
/* nothing to do */
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_startof(range, unit, extend, delta);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_endof(range, This->services->editor, unit, extend, delta);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_movestart(range, This->services->editor, unit, count, delta);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_movestart(range, This->services->editor, unit, count, delta);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_moveend(range, This->services->editor, unit, count, delta);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
|
|
LONG *length)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
FIXME("not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
|
|
LONG flags, LONG *length)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
|
|
LONG flags, LONG *length)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, count, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%p): stub\n", This, v);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_copy_or_cut(range, This->services->editor, TRUE, v);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
ITextRange *range = NULL;
|
|
HRESULT hr;
|
|
|
|
TRACE("(%p)->(%p)\n", This, v);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
|
|
hr = textrange_copy_or_cut(range, This->services->editor, FALSE, v);
|
|
ITextRange_Release(range);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %lx): stub\n", This, debugstr_variant(v), format);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
|
|
LONG *ret)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s %lx %p): stub\n", This, debugstr_variant(v), format, ret);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, ret);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld): stub\n", This, type);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %p %p): stub\n", This, type, cx, cy);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
|
|
LONG extend)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld %ld): stub\n", This, x, y, type, extend);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld): stub\n", This, value);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, ppv);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/*** ITextSelection methods ***/
|
|
static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, flags);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%lx): stub\n", This, flags);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, type);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
|
|
LONG extend, LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
|
|
LONG extend, LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
|
|
LONG extend, LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
|
|
LONG extend, LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
|
|
LONG *delta)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, extend, delta);
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
|
|
{
|
|
struct text_selection *This = impl_from_ITextSelection(me);
|
|
|
|
FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
|
|
|
|
if (!This->services)
|
|
return CO_E_RELEASED;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const ITextSelectionVtbl tsvt = {
|
|
ITextSelection_fnQueryInterface,
|
|
ITextSelection_fnAddRef,
|
|
ITextSelection_fnRelease,
|
|
ITextSelection_fnGetTypeInfoCount,
|
|
ITextSelection_fnGetTypeInfo,
|
|
ITextSelection_fnGetIDsOfNames,
|
|
ITextSelection_fnInvoke,
|
|
ITextSelection_fnGetText,
|
|
ITextSelection_fnSetText,
|
|
ITextSelection_fnGetChar,
|
|
ITextSelection_fnSetChar,
|
|
ITextSelection_fnGetDuplicate,
|
|
ITextSelection_fnGetFormattedText,
|
|
ITextSelection_fnSetFormattedText,
|
|
ITextSelection_fnGetStart,
|
|
ITextSelection_fnSetStart,
|
|
ITextSelection_fnGetEnd,
|
|
ITextSelection_fnSetEnd,
|
|
ITextSelection_fnGetFont,
|
|
ITextSelection_fnSetFont,
|
|
ITextSelection_fnGetPara,
|
|
ITextSelection_fnSetPara,
|
|
ITextSelection_fnGetStoryLength,
|
|
ITextSelection_fnGetStoryType,
|
|
ITextSelection_fnCollapse,
|
|
ITextSelection_fnExpand,
|
|
ITextSelection_fnGetIndex,
|
|
ITextSelection_fnSetIndex,
|
|
ITextSelection_fnSetRange,
|
|
ITextSelection_fnInRange,
|
|
ITextSelection_fnInStory,
|
|
ITextSelection_fnIsEqual,
|
|
ITextSelection_fnSelect,
|
|
ITextSelection_fnStartOf,
|
|
ITextSelection_fnEndOf,
|
|
ITextSelection_fnMove,
|
|
ITextSelection_fnMoveStart,
|
|
ITextSelection_fnMoveEnd,
|
|
ITextSelection_fnMoveWhile,
|
|
ITextSelection_fnMoveStartWhile,
|
|
ITextSelection_fnMoveEndWhile,
|
|
ITextSelection_fnMoveUntil,
|
|
ITextSelection_fnMoveStartUntil,
|
|
ITextSelection_fnMoveEndUntil,
|
|
ITextSelection_fnFindText,
|
|
ITextSelection_fnFindTextStart,
|
|
ITextSelection_fnFindTextEnd,
|
|
ITextSelection_fnDelete,
|
|
ITextSelection_fnCut,
|
|
ITextSelection_fnCopy,
|
|
ITextSelection_fnPaste,
|
|
ITextSelection_fnCanPaste,
|
|
ITextSelection_fnCanEdit,
|
|
ITextSelection_fnChangeCase,
|
|
ITextSelection_fnGetPoint,
|
|
ITextSelection_fnSetPoint,
|
|
ITextSelection_fnScrollIntoView,
|
|
ITextSelection_fnGetEmbeddedObject,
|
|
ITextSelection_fnGetFlags,
|
|
ITextSelection_fnSetFlags,
|
|
ITextSelection_fnGetType,
|
|
ITextSelection_fnMoveLeft,
|
|
ITextSelection_fnMoveRight,
|
|
ITextSelection_fnMoveUp,
|
|
ITextSelection_fnMoveDown,
|
|
ITextSelection_fnHomeKey,
|
|
ITextSelection_fnEndKey,
|
|
ITextSelection_fnTypeText
|
|
};
|
|
|
|
static struct text_selection *text_selection_create(struct text_services *services)
|
|
{
|
|
struct text_selection *txtSel = heap_alloc(sizeof *txtSel);
|
|
if (!txtSel)
|
|
return NULL;
|
|
|
|
txtSel->ITextSelection_iface.lpVtbl = &tsvt;
|
|
txtSel->ref = 1;
|
|
txtSel->services = services;
|
|
return txtSel;
|
|
}
|
|
|
|
static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
|
|
{
|
|
/* sizel is in .01 millimeters, sz in pixels */
|
|
sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
|
|
sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* ME_GetOLEObjectSize
|
|
*
|
|
* Sets run extent for OLE objects.
|
|
*/
|
|
void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
|
|
{
|
|
IDataObject* ido;
|
|
FORMATETC fmt;
|
|
STGMEDIUM stgm;
|
|
DIBSECTION dibsect;
|
|
ENHMETAHEADER emh;
|
|
|
|
assert(run->nFlags & MERF_GRAPHICS);
|
|
assert(run->reobj);
|
|
|
|
if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
|
|
{
|
|
convert_sizel(c, &run->reobj->obj.sizel, pSize);
|
|
if (c->editor->nZoomNumerator != 0)
|
|
{
|
|
pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!run->reobj->obj.poleobj)
|
|
{
|
|
pSize->cx = pSize->cy = 0;
|
|
return;
|
|
}
|
|
|
|
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;
|
|
return;
|
|
}
|
|
fmt.cfFormat = CF_BITMAP;
|
|
fmt.ptd = NULL;
|
|
fmt.dwAspect = DVASPECT_CONTENT;
|
|
fmt.lindex = -1;
|
|
fmt.tymed = TYMED_GDI;
|
|
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
|
|
{
|
|
fmt.cfFormat = CF_ENHMETAFILE;
|
|
fmt.tymed = TYMED_ENHMF;
|
|
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
|
|
{
|
|
FIXME("unsupported format\n");
|
|
pSize->cx = pSize->cy = 0;
|
|
IDataObject_Release(ido);
|
|
return;
|
|
}
|
|
}
|
|
IDataObject_Release(ido);
|
|
|
|
switch (stgm.tymed)
|
|
{
|
|
case TYMED_GDI:
|
|
GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
|
|
pSize->cx = dibsect.dsBm.bmWidth;
|
|
pSize->cy = dibsect.dsBm.bmHeight;
|
|
break;
|
|
case TYMED_ENHMF:
|
|
GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
|
|
pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
|
|
pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
|
|
break;
|
|
default:
|
|
FIXME("Unsupported tymed %ld\n", stgm.tymed);
|
|
break;
|
|
}
|
|
ReleaseStgMedium(&stgm);
|
|
if (c->editor->nZoomNumerator != 0)
|
|
{
|
|
pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
}
|
|
}
|
|
|
|
void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected )
|
|
{
|
|
IDataObject* ido;
|
|
FORMATETC fmt;
|
|
STGMEDIUM stgm;
|
|
DIBSECTION dibsect;
|
|
ENHMETAHEADER emh;
|
|
HDC hMemDC;
|
|
SIZE sz;
|
|
BOOL has_size;
|
|
HBITMAP old_bm;
|
|
RECT rc;
|
|
|
|
assert(run->nFlags & MERF_GRAPHICS);
|
|
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->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
|
|
fmt.cfFormat = CF_BITMAP;
|
|
fmt.ptd = NULL;
|
|
fmt.dwAspect = DVASPECT_CONTENT;
|
|
fmt.lindex = -1;
|
|
fmt.tymed = TYMED_GDI;
|
|
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
|
|
{
|
|
fmt.cfFormat = CF_ENHMETAFILE;
|
|
fmt.tymed = TYMED_ENHMF;
|
|
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
|
|
{
|
|
FIXME("Couldn't get storage medium\n");
|
|
IDataObject_Release(ido);
|
|
return;
|
|
}
|
|
}
|
|
IDataObject_Release(ido);
|
|
|
|
switch (stgm.tymed)
|
|
{
|
|
case TYMED_GDI:
|
|
GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
|
|
hMemDC = CreateCompatibleDC(c->hDC);
|
|
old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
|
|
if (has_size)
|
|
{
|
|
convert_sizel(c, &run->reobj->obj.sizel, &sz);
|
|
} else {
|
|
sz.cx = dibsect.dsBm.bmWidth;
|
|
sz.cy = dibsect.dsBm.bmHeight;
|
|
}
|
|
if (c->editor->nZoomNumerator != 0)
|
|
{
|
|
sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
}
|
|
StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
|
|
hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
|
|
|
|
SelectObject(hMemDC, old_bm);
|
|
DeleteDC(hMemDC);
|
|
break;
|
|
case TYMED_ENHMF:
|
|
GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
|
|
if (has_size)
|
|
{
|
|
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;
|
|
}
|
|
if (c->editor->nZoomNumerator != 0)
|
|
{
|
|
sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
|
|
}
|
|
|
|
rc.left = x;
|
|
rc.top = y - sz.cy;
|
|
rc.right = x + sz.cx;
|
|
rc.bottom = y;
|
|
PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
|
|
break;
|
|
default:
|
|
FIXME("Unsupported tymed %ld\n", stgm.tymed);
|
|
selected = FALSE;
|
|
break;
|
|
}
|
|
ReleaseStgMedium(&stgm);
|
|
|
|
if (selected && !c->editor->bHideSelection)
|
|
PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
|
|
}
|
|
|
|
void ME_DeleteReObject(struct re_object *reobj)
|
|
{
|
|
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, DWORD flags)
|
|
{
|
|
*dst = *src;
|
|
dst->poleobj = NULL;
|
|
dst->pstg = NULL;
|
|
dst->polesite = NULL;
|
|
|
|
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 richole_release_children( struct text_services *services )
|
|
{
|
|
ITextRangeImpl *range;
|
|
IOleClientSiteImpl *site;
|
|
|
|
if (services->text_selection)
|
|
{
|
|
services->text_selection->services = NULL;
|
|
ITextSelection_Release( &services->text_selection->ITextSelection_iface );
|
|
}
|
|
|
|
LIST_FOR_EACH_ENTRY( range, &services->rangelist, ITextRangeImpl, child.entry )
|
|
range->child.reole = NULL;
|
|
|
|
LIST_FOR_EACH_ENTRY( site, &services->clientsites, IOleClientSiteImpl, child.entry )
|
|
site->child.reole = NULL;
|
|
}
|