5d74d291490de2101b13443de7dc6c70260b1852
[reactos.git] / reactos / dll / win32 / mshtml / selection.c
1 /*
2 * Copyright 2006 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define WIN32_NO_STATUS
20 #define _INC_WINDOWS
21
22 #include <stdarg.h>
23
24 #define COBJMACROS
25
26 #include <windef.h>
27 #include <winbase.h>
28 //#include "winuser.h"
29 #include <ole2.h>
30
31 #include <wine/debug.h>
32
33 #include "mshtml_private.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36
37 typedef struct {
38 IHTMLSelectionObject IHTMLSelectionObject_iface;
39
40 LONG ref;
41
42 nsISelection *nsselection;
43 HTMLDocumentNode *doc;
44
45 struct list entry;
46 } HTMLSelectionObject;
47
48 static inline HTMLSelectionObject *impl_from_IHTMLSelectionObject(IHTMLSelectionObject *iface)
49 {
50 return CONTAINING_RECORD(iface, HTMLSelectionObject, IHTMLSelectionObject_iface);
51 }
52
53 static HRESULT WINAPI HTMLSelectionObject_QueryInterface(IHTMLSelectionObject *iface,
54 REFIID riid, void **ppv)
55 {
56 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
57
58 *ppv = NULL;
59
60 if(IsEqualGUID(&IID_IUnknown, riid)) {
61 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
62 *ppv = &This->IHTMLSelectionObject_iface;
63 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
64 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
65 *ppv = &This->IHTMLSelectionObject_iface;
66 }else if(IsEqualGUID(&IID_IHTMLSelectionObject, riid)) {
67 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
68 *ppv = &This->IHTMLSelectionObject_iface;
69 }
70
71 if(*ppv) {
72 IUnknown_AddRef((IUnknown*)*ppv);
73 return S_OK;
74 }
75
76 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
77 return E_NOINTERFACE;
78 }
79
80 static ULONG WINAPI HTMLSelectionObject_AddRef(IHTMLSelectionObject *iface)
81 {
82 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
83 LONG ref = InterlockedIncrement(&This->ref);
84
85 TRACE("(%p) ref=%d\n", This, ref);
86
87 return ref;
88 }
89
90 static ULONG WINAPI HTMLSelectionObject_Release(IHTMLSelectionObject *iface)
91 {
92 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
93 LONG ref = InterlockedDecrement(&This->ref);
94
95 TRACE("(%p) ref=%d\n", This, ref);
96
97 if(!ref) {
98 if(This->nsselection)
99 nsISelection_Release(This->nsselection);
100 if(This->doc)
101 list_remove(&This->entry);
102 heap_free(This);
103 }
104
105 return ref;
106 }
107
108 static HRESULT WINAPI HTMLSelectionObject_GetTypeInfoCount(IHTMLSelectionObject *iface, UINT *pctinfo)
109 {
110 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
111 FIXME("(%p)->(%p)\n", This, pctinfo);
112 return E_NOTIMPL;
113 }
114
115 static HRESULT WINAPI HTMLSelectionObject_GetTypeInfo(IHTMLSelectionObject *iface, UINT iTInfo,
116 LCID lcid, ITypeInfo **ppTInfo)
117 {
118 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
119 FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
120 return E_NOTIMPL;
121 }
122
123 static HRESULT WINAPI HTMLSelectionObject_GetIDsOfNames(IHTMLSelectionObject *iface, REFIID riid,
124 LPOLESTR *rgszNames, UINT cNames,
125 LCID lcid, DISPID *rgDispId)
126 {
127 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
128 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
129 lcid, rgDispId);
130 return E_NOTIMPL;
131 }
132
133 static HRESULT WINAPI HTMLSelectionObject_Invoke(IHTMLSelectionObject *iface, DISPID dispIdMember,
134 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
135 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
136 {
137 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
138 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
139 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
140 return E_NOTIMPL;
141 }
142
143 static HRESULT WINAPI HTMLSelectionObject_createRange(IHTMLSelectionObject *iface, IDispatch **range)
144 {
145 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
146 IHTMLTxtRange *range_obj = NULL;
147 nsIDOMRange *nsrange = NULL;
148 HRESULT hres;
149
150 TRACE("(%p)->(%p)\n", This, range);
151
152 if(This->nsselection) {
153 LONG nsrange_cnt = 0;
154 nsresult nsres;
155
156 nsISelection_GetRangeCount(This->nsselection, &nsrange_cnt);
157 if(!nsrange_cnt) {
158 nsIDOMHTMLElement *nsbody = NULL;
159
160 TRACE("nsrange_cnt = 0\n");
161
162 if(!This->doc->nsdoc) {
163 WARN("nsdoc is NULL\n");
164 return E_UNEXPECTED;
165 }
166
167 nsres = nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nsbody);
168 if(NS_FAILED(nsres) || !nsbody) {
169 ERR("Could not get body: %08x\n", nsres);
170 return E_FAIL;
171 }
172
173 nsres = nsISelection_Collapse(This->nsselection, (nsIDOMNode*)nsbody, 0);
174 nsIDOMHTMLElement_Release(nsbody);
175 if(NS_FAILED(nsres))
176 ERR("Collapse failed: %08x\n", nsres);
177 }else if(nsrange_cnt > 1) {
178 FIXME("range_cnt = %d\n", nsrange_cnt);
179 }
180
181 nsres = nsISelection_GetRangeAt(This->nsselection, 0, &nsrange);
182 if(NS_FAILED(nsres))
183 ERR("GetRangeAt failed: %08x\n", nsres);
184 }
185
186 hres = HTMLTxtRange_Create(This->doc, nsrange, &range_obj);
187
188 if (nsrange) nsIDOMRange_Release(nsrange);
189 *range = (IDispatch*)range_obj;
190 return hres;
191 }
192
193 static HRESULT WINAPI HTMLSelectionObject_empty(IHTMLSelectionObject *iface)
194 {
195 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
196 FIXME("(%p)\n", This);
197 return E_NOTIMPL;
198 }
199
200 static HRESULT WINAPI HTMLSelectionObject_clear(IHTMLSelectionObject *iface)
201 {
202 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
203 FIXME("(%p)\n", This);
204 return E_NOTIMPL;
205 }
206
207 static HRESULT WINAPI HTMLSelectionObject_get_type(IHTMLSelectionObject *iface, BSTR *p)
208 {
209 HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface);
210 cpp_bool collapsed = TRUE;
211
212 static const WCHAR wszNone[] = {'N','o','n','e',0};
213 static const WCHAR wszText[] = {'T','e','x','t',0};
214
215 TRACE("(%p)->(%p)\n", This, p);
216
217 if(This->nsselection)
218 nsISelection_GetIsCollapsed(This->nsselection, &collapsed);
219
220 *p = SysAllocString(collapsed ? wszNone : wszText); /* FIXME: control */
221 TRACE("ret %s\n", debugstr_w(*p));
222 return S_OK;
223 }
224
225 static const IHTMLSelectionObjectVtbl HTMLSelectionObjectVtbl = {
226 HTMLSelectionObject_QueryInterface,
227 HTMLSelectionObject_AddRef,
228 HTMLSelectionObject_Release,
229 HTMLSelectionObject_GetTypeInfoCount,
230 HTMLSelectionObject_GetTypeInfo,
231 HTMLSelectionObject_GetIDsOfNames,
232 HTMLSelectionObject_Invoke,
233 HTMLSelectionObject_createRange,
234 HTMLSelectionObject_empty,
235 HTMLSelectionObject_clear,
236 HTMLSelectionObject_get_type
237 };
238
239 HRESULT HTMLSelectionObject_Create(HTMLDocumentNode *doc, nsISelection *nsselection, IHTMLSelectionObject **ret)
240 {
241 HTMLSelectionObject *selection;
242
243 selection = heap_alloc(sizeof(HTMLSelectionObject));
244 if(!selection)
245 return E_OUTOFMEMORY;
246
247 selection->IHTMLSelectionObject_iface.lpVtbl = &HTMLSelectionObjectVtbl;
248 selection->ref = 1;
249 selection->nsselection = nsselection; /* We shouldn't call AddRef here */
250
251 selection->doc = doc;
252 list_add_head(&doc->selection_list, &selection->entry);
253
254 *ret = &selection->IHTMLSelectionObject_iface;
255 return S_OK;
256 }
257
258 void detach_selection(HTMLDocumentNode *This)
259 {
260 HTMLSelectionObject *iter;
261
262 LIST_FOR_EACH_ENTRY(iter, &This->selection_list, HTMLSelectionObject, entry) {
263 iter->doc = NULL;
264 }
265 }