dmusic: Avoid swallowing collection Load failures.
[wine.git] / dlls / msctf / range.c
blobc42d91d168207972340793fd0ec2fd2c8c16bcae
1 /*
2 * ITfRange implementation
4 * Copyright 2009 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "wine/debug.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winuser.h"
30 #include "shlwapi.h"
31 #include "winerror.h"
32 #include "objbase.h"
34 #include "msctf.h"
35 #include "msctf_internal.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
39 typedef struct tagRange {
40 ITfRangeACP ITfRangeACP_iface;
41 LONG refCount;
43 ITfContext *context;
45 TfGravity gravityStart, gravityEnd;
46 DWORD anchorStart, anchorEnd;
48 } Range;
50 static inline Range *impl_from_ITfRangeACP(ITfRangeACP *iface)
52 return CONTAINING_RECORD(iface, Range, ITfRangeACP_iface);
55 static Range *unsafe_impl_from_ITfRange(ITfRange *iface)
57 return CONTAINING_RECORD(iface, Range, ITfRangeACP_iface);
60 static void Range_Destructor(Range *This)
62 TRACE("destroying %p\n", This);
63 ITfContext_Release(This->context);
64 free(This);
67 static HRESULT WINAPI Range_QueryInterface(ITfRangeACP *iface, REFIID iid, LPVOID *ppvOut)
69 Range *range = impl_from_ITfRangeACP(iface);
71 *ppvOut = NULL;
73 if (IsEqualIID(iid, &IID_IUnknown) ||
74 IsEqualIID(iid, &IID_ITfRange) ||
75 IsEqualIID(iid, &IID_ITfRangeACP))
77 *ppvOut = &range->ITfRangeACP_iface;
80 if (*ppvOut)
82 ITfRangeACP_AddRef(iface);
83 return S_OK;
86 WARN("unsupported interface: %s\n", debugstr_guid(iid));
87 return E_NOINTERFACE;
90 static ULONG WINAPI Range_AddRef(ITfRangeACP *iface)
92 Range *range = impl_from_ITfRangeACP(iface);
93 return InterlockedIncrement(&range->refCount);
96 static ULONG WINAPI Range_Release(ITfRangeACP *iface)
98 Range *range = impl_from_ITfRangeACP(iface);
99 ULONG ret;
101 ret = InterlockedDecrement(&range->refCount);
102 if (ret == 0)
103 Range_Destructor(range);
104 return ret;
107 static HRESULT WINAPI Range_GetText(ITfRangeACP *iface, TfEditCookie ec,
108 DWORD dwFlags, WCHAR *pchText, ULONG cchMax, ULONG *pcch)
110 FIXME("STUB:(%p)\n", iface);
111 return E_NOTIMPL;
114 static HRESULT WINAPI Range_SetText(ITfRangeACP *iface, TfEditCookie ec,
115 DWORD dwFlags, const WCHAR *pchText, LONG cch)
117 FIXME("STUB:(%p)\n", iface);
118 return E_NOTIMPL;
121 static HRESULT WINAPI Range_GetFormattedText(ITfRangeACP *iface, TfEditCookie ec,
122 IDataObject **ppDataObject)
124 FIXME("STUB:(%p)\n", iface);
125 return E_NOTIMPL;
128 static HRESULT WINAPI Range_GetEmbedded(ITfRangeACP *iface, TfEditCookie ec,
129 REFGUID rguidService, REFIID riid, IUnknown **ppunk)
131 FIXME("STUB:(%p)\n", iface);
132 return E_NOTIMPL;
135 static HRESULT WINAPI Range_InsertEmbedded(ITfRangeACP *iface, TfEditCookie ec,
136 DWORD dwFlags, IDataObject *pDataObject)
138 FIXME("STUB:(%p)\n", iface);
139 return E_NOTIMPL;
142 static HRESULT WINAPI Range_ShiftStart(ITfRangeACP *iface, TfEditCookie ec,
143 LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt)
145 FIXME("STUB:(%p)\n", iface);
146 return E_NOTIMPL;
149 static HRESULT WINAPI Range_ShiftEnd(ITfRangeACP *iface, TfEditCookie ec,
150 LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt)
152 FIXME("STUB:(%p)\n", iface);
153 return E_NOTIMPL;
156 static HRESULT WINAPI Range_ShiftStartToRange(ITfRangeACP *iface, TfEditCookie ec,
157 ITfRange *pRange, TfAnchor aPos)
159 FIXME("STUB:(%p)\n", iface);
160 return E_NOTIMPL;
163 static HRESULT WINAPI Range_ShiftEndToRange(ITfRangeACP *iface, TfEditCookie ec,
164 ITfRange *pRange, TfAnchor aPos)
166 FIXME("STUB:(%p)\n", iface);
167 return E_NOTIMPL;
170 static HRESULT WINAPI Range_ShiftStartRegion(ITfRangeACP *iface, TfEditCookie ec,
171 TfShiftDir dir, BOOL *pfNoRegion)
173 FIXME("STUB:(%p)\n", iface);
174 return E_NOTIMPL;
177 static HRESULT WINAPI Range_ShiftEndRegion(ITfRangeACP *iface, TfEditCookie ec,
178 TfShiftDir dir, BOOL *pfNoRegion)
180 FIXME("STUB:(%p)\n", iface);
181 return E_NOTIMPL;
184 static HRESULT WINAPI Range_IsEmpty(ITfRangeACP *iface, TfEditCookie ec,
185 BOOL *pfEmpty)
187 FIXME("STUB:(%p)\n", iface);
188 return E_NOTIMPL;
191 static HRESULT WINAPI Range_Collapse(ITfRangeACP *iface, TfEditCookie ec,
192 TfAnchor aPos)
194 Range *range = impl_from_ITfRangeACP(iface);
196 TRACE("%p, %li, %i.\n", iface, ec, aPos);
198 switch (aPos)
200 case TF_ANCHOR_START:
201 range->anchorEnd = range->anchorStart;
202 break;
203 case TF_ANCHOR_END:
204 range->anchorStart = range->anchorEnd;
205 break;
206 default:
207 return E_INVALIDARG;
210 return S_OK;
213 static HRESULT WINAPI Range_IsEqualStart(ITfRangeACP *iface, TfEditCookie ec,
214 ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual)
216 FIXME("STUB:(%p)\n", iface);
217 return E_NOTIMPL;
220 static HRESULT WINAPI Range_IsEqualEnd(ITfRangeACP *iface, TfEditCookie ec,
221 ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual)
223 FIXME("STUB:(%p)\n", iface);
224 return E_NOTIMPL;
227 static HRESULT WINAPI Range_CompareStart(ITfRangeACP *iface, TfEditCookie ec,
228 ITfRange *pWith, TfAnchor aPos, LONG *plResult)
230 FIXME("STUB:(%p)\n", iface);
231 return E_NOTIMPL;
234 static HRESULT WINAPI Range_CompareEnd(ITfRangeACP *iface, TfEditCookie ec,
235 ITfRange *pWith, TfAnchor aPos, LONG *plResult)
237 FIXME("STUB:(%p)\n", iface);
238 return E_NOTIMPL;
241 static HRESULT WINAPI Range_AdjustForInsert(ITfRangeACP *iface, TfEditCookie ec,
242 ULONG cchInsert, BOOL *pfInsertOk)
244 FIXME("STUB:(%p)\n", iface);
245 return E_NOTIMPL;
248 static HRESULT WINAPI Range_GetGravity(ITfRangeACP *iface,
249 TfGravity *pgStart, TfGravity *pgEnd)
251 FIXME("STUB:(%p)\n", iface);
252 return E_NOTIMPL;
255 static HRESULT WINAPI Range_SetGravity(ITfRangeACP *iface, TfEditCookie ec,
256 TfGravity gStart, TfGravity gEnd)
258 FIXME("STUB:(%p)\n", iface);
259 return E_NOTIMPL;
262 static HRESULT WINAPI Range_Clone(ITfRangeACP *iface, ITfRange **ppClone)
264 FIXME("STUB:(%p)\n", iface);
265 return E_NOTIMPL;
268 static HRESULT WINAPI Range_GetContext(ITfRangeACP *iface, ITfContext **context)
270 Range *range = impl_from_ITfRangeACP(iface);
272 TRACE("%p, %p.\n", iface, context);
274 if (!context)
275 return E_INVALIDARG;
277 *context = range->context;
278 ITfContext_AddRef(*context);
280 return S_OK;
283 static HRESULT WINAPI Range_GetExtent(ITfRangeACP *iface, LONG *anchor, LONG *count)
285 FIXME("%p, %p, %p.\n", iface, anchor, count);
287 return E_NOTIMPL;
290 static HRESULT WINAPI Range_SetExtent(ITfRangeACP *iface, LONG anchor, LONG count)
292 FIXME("%p, %ld, %ld.\n", iface, anchor, count);
294 return E_NOTIMPL;
297 static const ITfRangeACPVtbl rangevtbl =
299 Range_QueryInterface,
300 Range_AddRef,
301 Range_Release,
302 Range_GetText,
303 Range_SetText,
304 Range_GetFormattedText,
305 Range_GetEmbedded,
306 Range_InsertEmbedded,
307 Range_ShiftStart,
308 Range_ShiftEnd,
309 Range_ShiftStartToRange,
310 Range_ShiftEndToRange,
311 Range_ShiftStartRegion,
312 Range_ShiftEndRegion,
313 Range_IsEmpty,
314 Range_Collapse,
315 Range_IsEqualStart,
316 Range_IsEqualEnd,
317 Range_CompareStart,
318 Range_CompareEnd,
319 Range_AdjustForInsert,
320 Range_GetGravity,
321 Range_SetGravity,
322 Range_Clone,
323 Range_GetContext,
324 Range_GetExtent,
325 Range_SetExtent,
328 HRESULT Range_Constructor(ITfContext *context, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut)
330 Range *This;
332 This = calloc(1, sizeof(Range));
333 if (This == NULL)
334 return E_OUTOFMEMORY;
336 TRACE("(%p) %p\n", This, context);
338 This->ITfRangeACP_iface.lpVtbl = &rangevtbl;
339 This->refCount = 1;
340 This->context = context;
341 ITfContext_AddRef(This->context);
342 This->anchorStart = anchorStart;
343 This->anchorEnd = anchorEnd;
345 *ppOut = (ITfRange *)&This->ITfRangeACP_iface;
347 TRACE("returning %p\n", *ppOut);
349 return S_OK;
352 /* Internal conversion functions */
354 HRESULT TF_SELECTION_to_TS_SELECTION_ACP(const TF_SELECTION *tf, TS_SELECTION_ACP *tsAcp)
356 Range *This;
358 if (!tf || !tsAcp || !tf->range)
359 return E_INVALIDARG;
361 This = unsafe_impl_from_ITfRange(tf->range);
363 tsAcp->acpStart = This->anchorStart;
364 tsAcp->acpEnd = This->anchorEnd;
365 tsAcp->style.ase = tf->style.ase;
366 tsAcp->style.fInterimChar = tf->style.fInterimChar;
367 return S_OK;