mshtml: Added beginning of IDM_PRINT implementation.
[wine/multimedia.git] / dlls / mshtml / olecmd.c
blob1e78f6678a5458f6a855b053b2807094068b7376
1 /*
2 * Copyright 2005-2006 Jacek Caban for CodeWeavers
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.
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.
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
19 #include "config.h"
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31 #include "shlguid.h"
32 #include "mshtmdid.h"
33 #include "idispids.h"
34 #include "mshtmcid.h"
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
39 #include "mshtml_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
43 #define NSCMD_BOLD "cmd_bold"
44 #define NSCMD_ITALIC "cmd_italic"
45 #define NSCMD_UNDERLINE "cmd_underline"
46 #define NSCMD_FONTCOLOR "cmd_fontColor"
47 #define NSCMD_ALIGN "cmd_align"
48 #define NSCMD_FONTFACE "cmd_fontFace"
49 #define NSCMD_INDENT "cmd_indent"
50 #define NSCMD_OUTDENT "cmd_outdent"
51 #define NSCMD_INSERTHR "cmd_insertHR"
52 #define NSCMD_UL "cmd_ul"
53 #define NSCMD_OL "cmd_ol"
55 #define NSSTATE_ATTRIBUTE "state_attribute"
56 #define NSSTATE_ALL "state_all"
58 #define NSALIGN_CENTER "center"
59 #define NSALIGN_LEFT "left"
60 #define NSALIGN_RIGHT "right"
62 /**********************************************************
63 * IOleCommandTarget implementation
66 #define CMDTARGET_THIS(iface) DEFINE_THIS(HTMLDocument, OleCommandTarget, iface)
68 static HRESULT exec_open(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
70 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
71 return E_NOTIMPL;
74 static HRESULT exec_new(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
76 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
77 return E_NOTIMPL;
80 static HRESULT exec_save(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
82 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
83 return E_NOTIMPL;
86 static HRESULT exec_save_as(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
88 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
89 return E_NOTIMPL;
92 static HRESULT exec_save_copy_as(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
94 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
95 return E_NOTIMPL;
98 static HRESULT exec_print(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
100 nsIInterfaceRequestor *iface_req;
101 nsIWebBrowserPrint *nsprint;
102 nsresult nsres;
104 TRACE("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
106 if(pvaOut)
107 FIXME("unsupported pvaOut\n");
108 if(pvaIn)
109 FIXME("unsupported pvaIn\n");
111 if(!This->nscontainer)
112 return S_OK;
114 nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser,
115 &IID_nsIInterfaceRequestor, (void**)&iface_req);
116 if(NS_FAILED(nsres)) {
117 ERR("Could not get nsIInterfaceRequestor: %08x\n", nsres);
118 return S_OK;
121 nsres = nsIInterfaceRequestor_GetInterface(iface_req, &IID_nsIWebBrowserPrint,
122 (void**)&nsprint);
123 nsIInterfaceRequestor_Release(iface_req);
124 if(NS_FAILED(nsres)) {
125 ERR("Could not get nsIWebBrowserPrint: %08x\n", nsres);
126 return S_OK;
129 nsres = nsIWebBrowserPrint_Print(nsprint, NULL, NULL);
130 if(NS_FAILED(nsres))
131 ERR("Print failed: %08x\n", nsres);
133 nsIWebBrowserPrint_Release(nsprint);
135 return S_OK;
138 static HRESULT exec_print_preview(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
140 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
141 return E_NOTIMPL;
144 static HRESULT exec_page_setup(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
146 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
147 return E_NOTIMPL;
150 static HRESULT exec_spell(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
152 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
153 return E_NOTIMPL;
156 static HRESULT exec_properties(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
158 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
159 return E_NOTIMPL;
162 static HRESULT exec_cut(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
164 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
165 return E_NOTIMPL;
168 static HRESULT exec_copy(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
170 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
171 return E_NOTIMPL;
174 static HRESULT exec_paste(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
176 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
177 return E_NOTIMPL;
180 static HRESULT exec_paste_special(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
182 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
183 return E_NOTIMPL;
186 static HRESULT exec_undo(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
188 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
189 return E_NOTIMPL;
192 static HRESULT exec_rendo(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
194 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
195 return E_NOTIMPL;
198 static HRESULT exec_select_all(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
200 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
201 return E_NOTIMPL;
204 static HRESULT exec_clear_selection(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
206 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
207 return E_NOTIMPL;
210 static HRESULT exec_zoom(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
212 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
213 return E_NOTIMPL;
216 static HRESULT exec_get_zoom_range(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
218 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
219 return E_NOTIMPL;
222 static HRESULT exec_refresh(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
224 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
225 return E_NOTIMPL;
228 static HRESULT exec_stop(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
230 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
231 return E_NOTIMPL;
234 static HRESULT exec_stop_download(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
236 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
237 return E_NOTIMPL;
240 static HRESULT exec_delete(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
242 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
243 return E_NOTIMPL;
246 static HRESULT exec_enable_interaction(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
248 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
249 return E_NOTIMPL;
252 static HRESULT exec_on_unload(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
254 TRACE("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
256 /* Tests show that we have nothing more to do here */
258 if(pvaOut) {
259 V_VT(pvaOut) = VT_BOOL;
260 V_BOOL(pvaOut) = VARIANT_TRUE;
263 return S_OK;
266 static HRESULT exec_show_page_setup(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
268 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
269 return E_NOTIMPL;
272 static HRESULT exec_show_print(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
274 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
275 return E_NOTIMPL;
278 static HRESULT exec_close(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
280 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
281 return E_NOTIMPL;
284 static HRESULT exec_set_print_template(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
286 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
287 return E_NOTIMPL;
290 static HRESULT exec_get_print_template(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
292 FIXME("(%p)->(%d %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
293 return E_NOTIMPL;
296 static void do_ns_command(NSContainer *This, const char *cmd, nsICommandParams *nsparam)
298 nsICommandManager *cmdmgr;
299 nsIInterfaceRequestor *iface_req;
300 nsresult nsres;
302 TRACE("(%p)\n", This);
304 nsres = nsIWebBrowser_QueryInterface(This->webbrowser,
305 &IID_nsIInterfaceRequestor, (void**)&iface_req);
306 if(NS_FAILED(nsres)) {
307 ERR("Could not get nsIInterfaceRequestor: %08x\n", nsres);
308 return;
311 nsres = nsIInterfaceRequestor_GetInterface(iface_req, &IID_nsICommandManager,
312 (void**)&cmdmgr);
313 nsIInterfaceRequestor_Release(iface_req);
314 if(NS_FAILED(nsres)) {
315 ERR("Could not get nsICommandManager: %08x\n", nsres);
316 return;
319 nsres = nsICommandManager_DoCommand(cmdmgr, cmd, nsparam, NULL);
320 if(NS_FAILED(nsres))
321 ERR("DoCommand(%s) failed: %08x\n", debugstr_a(cmd), nsres);
323 nsICommandManager_Release(cmdmgr);
326 static nsresult get_ns_command_state(NSContainer *This, const char *cmd, nsICommandParams *nsparam)
328 nsICommandManager *cmdmgr;
329 nsIInterfaceRequestor *iface_req;
330 nsresult nsres;
332 nsres = nsIWebBrowser_QueryInterface(This->webbrowser,
333 &IID_nsIInterfaceRequestor, (void**)&iface_req);
334 if(NS_FAILED(nsres)) {
335 ERR("Could not get nsIInterfaceRequestor: %08x\n", nsres);
336 return nsres;
339 nsres = nsIInterfaceRequestor_GetInterface(iface_req, &IID_nsICommandManager,
340 (void**)&cmdmgr);
341 nsIInterfaceRequestor_Release(iface_req);
342 if(NS_FAILED(nsres)) {
343 ERR("Could not get nsICommandManager: %08x\n", nsres);
344 return nsres;
347 nsres = nsICommandManager_GetCommandState(cmdmgr, cmd, NULL, nsparam);
348 if(NS_FAILED(nsres))
349 ERR("GetCommandState(%s) failed: %08x\n", debugstr_a(cmd), nsres);
351 nsICommandManager_Release(cmdmgr);
352 return nsres;
355 static DWORD query_edit_status(HTMLDocument *This, const char *nscmd)
357 nsICommandParams *nsparam;
358 PRBool b = FALSE;
360 if(This->usermode != EDITMODE || This->readystate < READYSTATE_INTERACTIVE)
361 return OLECMDF_SUPPORTED;
363 if(This->nscontainer && nscmd) {
364 nsparam = create_nscommand_params();
365 get_ns_command_state(This->nscontainer, nscmd, nsparam);
367 nsICommandParams_GetBooleanValue(nsparam, NSSTATE_ALL, &b);
369 nsICommandParams_Release(nsparam);
372 return OLECMDF_SUPPORTED | OLECMDF_ENABLED | (b ? OLECMDF_LATCHED : 0);
375 static DWORD query_align_status(HTMLDocument *This, const char *align_str)
377 nsICommandParams *nsparam;
378 char *align = NULL;
380 if(This->usermode != EDITMODE || This->readystate < READYSTATE_INTERACTIVE)
381 return OLECMDF_SUPPORTED;
383 if(This->nscontainer) {
384 nsparam = create_nscommand_params();
385 get_ns_command_state(This->nscontainer, NSCMD_ALIGN, nsparam);
387 nsICommandParams_GetCStringValue(nsparam, NSSTATE_ATTRIBUTE, &align);
389 nsICommandParams_Release(nsparam);
392 return OLECMDF_SUPPORTED | OLECMDF_ENABLED | (align && !strcmp(align_str, align) ? OLECMDF_LATCHED : 0);
395 static void set_ns_align(HTMLDocument *This, const char *align_str)
397 nsICommandParams *nsparam;
399 if(!This->nscontainer)
400 return;
402 nsparam = create_nscommand_params();
403 nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, align_str);
405 do_ns_command(This->nscontainer, NSCMD_ALIGN, nsparam);
407 nsICommandParams_Release(nsparam);
410 static HRESULT exec_fontname(HTMLDocument *This, VARIANT *in, VARIANT *out)
412 TRACE("(%p)->(%p %p)\n", This, in, out);
414 if(!This->nscontainer)
415 return E_FAIL;
417 if(in) {
418 nsICommandParams *nsparam = create_nscommand_params();
419 char *stra;
420 DWORD len;
422 if(V_VT(in) != VT_BSTR) {
423 FIXME("Unsupported vt=%d\n", V_VT(out));
424 return E_INVALIDARG;
427 len = WideCharToMultiByte(CP_ACP, 0, V_BSTR(in), -1, NULL, 0, NULL, NULL);
428 stra = mshtml_alloc(len);
429 WideCharToMultiByte(CP_ACP, 0, V_BSTR(in), -1, stra, -1, NULL, NULL);
430 nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, stra);
431 mshtml_free(stra);
433 do_ns_command(This->nscontainer, NSCMD_FONTFACE, nsparam);
435 nsICommandParams_Release(nsparam);
438 if(out) {
439 nsICommandParams *nsparam;
440 LPWSTR strw;
441 char *stra;
442 DWORD len;
443 nsresult nsres;
445 if(V_VT(out) != VT_BSTR) {
446 FIXME("Unsupported vt=%d\n", V_VT(out));
447 return E_INVALIDARG;
450 nsparam = create_nscommand_params();
452 nsres = get_ns_command_state(This->nscontainer, NSCMD_FONTFACE, nsparam);
453 if(NS_FAILED(nsres))
454 return S_OK;
456 nsICommandParams_GetCStringValue(nsparam, NSSTATE_ATTRIBUTE, &stra);
457 nsICommandParams_Release(nsparam);
459 len = MultiByteToWideChar(CP_ACP, 0, stra, -1, NULL, 0);
460 strw = mshtml_alloc(len*sizeof(WCHAR));
461 MultiByteToWideChar(CP_ACP, 0, stra, -1, strw, -1);
462 nsfree(stra);
464 V_BSTR(out) = SysAllocString(strw);
465 mshtml_free(strw);
468 return S_OK;
471 static HRESULT exec_forecolor(HTMLDocument *This, VARIANT *in, VARIANT *out)
473 TRACE("(%p)->(%p %p)\n", This, in, out);
475 if(in) {
476 if(V_VT(in) == VT_I4) {
477 nsICommandParams *nsparam = create_nscommand_params();
478 char color_str[10];
480 sprintf(color_str, "#%02x%02x%02x",
481 V_I4(in)&0xff, (V_I4(in)>>8)&0xff, (V_I4(in)>>16)&0xff);
483 nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, color_str);
484 do_ns_command(This->nscontainer, NSCMD_FONTCOLOR, nsparam);
486 nsICommandParams_Release(nsparam);
487 }else {
488 FIXME("unsupported in vt=%d\n", V_VT(in));
492 if(out) {
493 FIXME("unsupported out\n");
494 return E_NOTIMPL;
497 return S_OK;
500 static HRESULT exec_fontsize(HTMLDocument *This, VARIANT *in, VARIANT *out)
502 TRACE("(%p)->(%p %p)\n", This, in, out);
504 if(out) {
505 WCHAR val[10] = {0};
507 switch(V_VT(out)) {
508 case VT_I4:
509 get_font_size(This, val);
510 V_I4(out) = strtolW(val, NULL, 10);
511 break;
512 case VT_BSTR:
513 get_font_size(This, val);
514 V_BSTR(out) = SysAllocString(val);
515 break;
516 default:
517 FIXME("unsupported vt %d\n", V_VT(out));
521 if(in) {
522 switch(V_VT(in)) {
523 case VT_I4: {
524 WCHAR size[10];
525 static const WCHAR format[] = {'%','d',0};
526 wsprintfW(size, format, V_I4(in));
527 set_font_size(This, size);
528 break;
530 case VT_BSTR:
531 set_font_size(This, V_BSTR(in));
532 break;
533 default:
534 FIXME("unsupported vt %d\n", V_VT(out));
538 return S_OK;
541 static HRESULT exec_bold(HTMLDocument *This)
543 TRACE("(%p)\n", This);
545 if(This->nscontainer)
546 do_ns_command(This->nscontainer, NSCMD_BOLD, NULL);
548 return S_OK;
551 static HRESULT exec_italic(HTMLDocument *This)
553 TRACE("(%p)\n", This);
555 if(This->nscontainer)
556 do_ns_command(This->nscontainer, NSCMD_ITALIC, NULL);
558 return S_OK;
561 static HRESULT exec_justifycenter(HTMLDocument *This)
563 TRACE("(%p)\n", This);
564 set_ns_align(This, NSALIGN_CENTER);
565 return S_OK;
568 static HRESULT exec_justifyleft(HTMLDocument *This)
570 TRACE("(%p)\n", This);
571 set_ns_align(This, NSALIGN_LEFT);
572 return S_OK;
575 static HRESULT exec_justifyright(HTMLDocument *This)
577 TRACE("(%p)\n", This);
578 set_ns_align(This, NSALIGN_RIGHT);
579 return S_OK;
582 static HRESULT exec_underline(HTMLDocument *This)
584 TRACE("(%p)\n", This);
586 if(This->nscontainer)
587 do_ns_command(This->nscontainer, NSCMD_UNDERLINE, NULL);
589 return S_OK;
592 static HRESULT exec_browsemode(HTMLDocument *This)
594 WARN("(%p)\n", This);
596 This->usermode = BROWSEMODE;
598 return S_OK;
601 static void setup_ns_editing(NSContainer *This)
603 nsIInterfaceRequestor *iface_req;
604 nsIEditingSession *editing_session = NULL;
605 nsIURIContentListener *listener = NULL;
606 nsIDOMWindow *dom_window = NULL;
607 nsresult nsres;
609 nsres = nsIWebBrowser_QueryInterface(This->webbrowser,
610 &IID_nsIInterfaceRequestor, (void**)&iface_req);
611 if(NS_FAILED(nsres)) {
612 ERR("Could not get nsIInterfaceRequestor: %08x\n", nsres);
613 return;
616 nsres = nsIInterfaceRequestor_GetInterface(iface_req, &IID_nsIEditingSession,
617 (void**)&editing_session);
618 nsIInterfaceRequestor_Release(iface_req);
619 if(NS_FAILED(nsres)) {
620 ERR("Could not get nsIEditingSession: %08x\n", nsres);
621 return;
624 nsres = nsIWebBrowser_GetContentDOMWindow(This->webbrowser, &dom_window);
625 if(NS_FAILED(nsres)) {
626 ERR("Could not get content DOM window: %08x\n", nsres);
627 nsIEditingSession_Release(editing_session);
628 return;
631 nsres = nsIEditingSession_MakeWindowEditable(editing_session, dom_window, NULL, FALSE);
632 nsIEditingSession_Release(editing_session);
633 nsIDOMWindow_Release(dom_window);
634 if(NS_FAILED(nsres)) {
635 ERR("MakeWindowEditable failed: %08x\n", nsres);
636 return;
639 /* MakeWindowEditable changes WebBrowser's parent URI content listener.
640 * It seams to be a bug in Gecko. To workaround it we set our content
641 * listener again and Gecko's one as its parent.
643 nsIWebBrowser_GetParentURIContentListener(This->webbrowser, &listener);
644 nsIURIContentListener_SetParentContentListener(NSURICL(This), listener);
645 nsIURIContentListener_Release(listener);
646 nsIWebBrowser_SetParentURIContentListener(This->webbrowser, NSURICL(This));
649 static HRESULT exec_editmode(HTMLDocument *This)
651 IMoniker *mon;
652 HRESULT hres;
654 static const WCHAR wszAboutBlank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
656 TRACE("(%p)\n", This);
658 This->usermode = EDITMODE;
660 if(This->frame)
661 IOleInPlaceFrame_SetStatusText(This->frame, NULL);
663 if(This->hostui) {
664 DOCHOSTUIINFO hostinfo;
666 memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
667 hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
668 hres = IDocHostUIHandler_GetHostInfo(This->hostui, &hostinfo);
669 if(SUCCEEDED(hres))
670 /* FIXME: use hostinfo */
671 TRACE("hostinfo = {%u %08x %08x %s %s}\n",
672 hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
673 debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
676 if(This->nscontainer)
677 setup_ns_editing(This->nscontainer);
679 hres = CreateURLMoniker(NULL, wszAboutBlank, &mon);
680 if(FAILED(hres)) {
681 FIXME("CreateURLMoniker failed: %08x\n", hres);
682 return hres;
685 return IPersistMoniker_Load(PERSISTMON(This), TRUE, mon, NULL, 0);
688 static HRESULT exec_baselinefont3(HTMLDocument *This)
690 FIXME("(%p)\n", This);
691 return S_OK;
694 static HRESULT exec_horizontalline(HTMLDocument *This)
696 TRACE("(%p)\n", This);
698 if(This->nscontainer)
699 do_ns_command(This->nscontainer, NSCMD_INSERTHR, NULL);
701 return S_OK;
704 static HRESULT exec_orderlist(HTMLDocument *This)
706 TRACE("(%p)\n", This);
708 if(This->nscontainer)
709 do_ns_command(This->nscontainer, NSCMD_OL, NULL);
711 return S_OK;
714 static HRESULT exec_unorderlist(HTMLDocument *This)
716 TRACE("(%p)\n", This);
718 if(This->nscontainer)
719 do_ns_command(This->nscontainer, NSCMD_UL, NULL);
721 return S_OK;
724 static HRESULT exec_indent(HTMLDocument *This)
726 TRACE("(%p)\n", This);
728 if(This->nscontainer)
729 do_ns_command(This->nscontainer, NSCMD_INDENT, NULL);
731 return S_OK;
734 static HRESULT exec_outdent(HTMLDocument *This)
736 TRACE("(%p)\n", This);
738 if(This->nscontainer)
739 do_ns_command(This->nscontainer, NSCMD_OUTDENT, NULL);
741 return S_OK;
744 static const struct {
745 OLECMDF cmdf;
746 HRESULT (*func)(HTMLDocument*,DWORD,VARIANT*,VARIANT*);
747 } exec_table[OLECMDID_GETPRINTTEMPLATE+1] = {
748 {0},
749 { OLECMDF_SUPPORTED, exec_open }, /* OLECMDID_OPEN */
750 { OLECMDF_SUPPORTED, exec_new }, /* OLECMDID_NEW */
751 { OLECMDF_SUPPORTED, exec_save }, /* OLECMDID_SAVE */
752 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_save_as }, /* OLECMDID_SAVEAS */
753 { OLECMDF_SUPPORTED, exec_save_copy_as }, /* OLECMDID_SAVECOPYAS */
754 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_print }, /* OLECMDID_PRINT */
755 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_print_preview }, /* OLECMDID_PRINTPREVIEW */
756 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_page_setup }, /* OLECMDID_PAGESETUP */
757 { OLECMDF_SUPPORTED, exec_spell }, /* OLECMDID_SPELL */
758 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_properties }, /* OLECMDID_PROPERTIES */
759 { OLECMDF_SUPPORTED, exec_cut }, /* OLECMDID_CUT */
760 { OLECMDF_SUPPORTED, exec_copy }, /* OLECMDID_COPY */
761 { OLECMDF_SUPPORTED, exec_paste }, /* OLECMDID_PASTE */
762 { OLECMDF_SUPPORTED, exec_paste_special }, /* OLECMDID_PASTESPECIAL */
763 { OLECMDF_SUPPORTED, exec_undo }, /* OLECMDID_UNDO */
764 { OLECMDF_SUPPORTED, exec_rendo }, /* OLECMDID_REDO */
765 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_select_all }, /* OLECMDID_SELECTALL */
766 { OLECMDF_SUPPORTED, exec_clear_selection }, /* OLECMDID_CLEARSELECTION */
767 { OLECMDF_SUPPORTED, exec_zoom }, /* OLECMDID_ZOOM */
768 { OLECMDF_SUPPORTED, exec_get_zoom_range }, /* OLECMDID_GETZOOMRANGE */
769 {0},
770 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_refresh }, /* OLECMDID_REFRESH */
771 { OLECMDF_SUPPORTED|OLECMDF_ENABLED, exec_stop }, /* OLECMDID_STOP */
772 {0},{0},{0},{0},{0},{0},
773 { OLECMDF_SUPPORTED, exec_stop_download }, /* OLECMDID_STOPDOWNLOAD */
774 {0},{0},
775 { OLECMDF_SUPPORTED, exec_delete }, /* OLECMDID_DELETE */
776 {0},{0},
777 { OLECMDF_SUPPORTED, exec_enable_interaction }, /* OLECMDID_ENABLE_INTERACTION */
778 { OLECMDF_SUPPORTED, exec_on_unload }, /* OLECMDID_ONUNLOAD */
779 {0},{0},{0},{0},{0},
780 { OLECMDF_SUPPORTED, exec_show_page_setup }, /* OLECMDID_SHOWPAGESETUP */
781 { OLECMDF_SUPPORTED, exec_show_print }, /* OLECMDID_SHOWPRINT */
782 {0},{0},
783 { OLECMDF_SUPPORTED, exec_close }, /* OLECMDID_CLOSE */
784 {0},{0},{0},
785 { OLECMDF_SUPPORTED, exec_set_print_template }, /* OLECMDID_SETPRINTTEMPLATE */
786 { OLECMDF_SUPPORTED, exec_get_print_template } /* OLECMDID_GETPRINTTEMPLATE */
789 static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv)
791 HTMLDocument *This = CMDTARGET_THIS(iface);
792 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
795 static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface)
797 HTMLDocument *This = CMDTARGET_THIS(iface);
798 return IHTMLDocument2_AddRef(HTMLDOC(This));
801 static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface)
803 HTMLDocument *This = CMDTARGET_THIS(iface);
804 return IHTMLDocument_Release(HTMLDOC(This));
807 static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
808 ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
810 HTMLDocument *This = CMDTARGET_THIS(iface);
811 HRESULT hres = S_OK, hr;
813 TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
815 if(!pguidCmdGroup) {
816 ULONG i;
818 for(i=0; i<cCmds; i++) {
819 if(prgCmds[i].cmdID<OLECMDID_OPEN || prgCmds[i].cmdID>OLECMDID_GETPRINTTEMPLATE) {
820 WARN("Unsupported cmdID = %d\n", prgCmds[i].cmdID);
821 prgCmds[i].cmdf = 0;
822 hres = OLECMDERR_E_NOTSUPPORTED;
823 }else {
824 if(prgCmds[i].cmdID == OLECMDID_OPEN || prgCmds[i].cmdID == OLECMDID_NEW) {
825 IOleCommandTarget *cmdtrg = NULL;
826 OLECMD olecmd;
828 prgCmds[i].cmdf = OLECMDF_SUPPORTED;
829 if(This->client) {
830 hr = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget,
831 (void**)&cmdtrg);
832 if(SUCCEEDED(hr)) {
833 olecmd.cmdID = prgCmds[i].cmdID;
834 olecmd.cmdf = 0;
836 hr = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &olecmd, NULL);
837 if(SUCCEEDED(hr) && olecmd.cmdf)
838 prgCmds[i].cmdf = olecmd.cmdf;
840 }else {
841 ERR("This->client == NULL, native would crash\n");
843 }else {
844 prgCmds[i].cmdf = exec_table[prgCmds[i].cmdID].cmdf;
845 TRACE("cmdID = %d returning %x\n", prgCmds[i].cmdID, prgCmds[i].cmdf);
847 hres = S_OK;
851 if(pCmdText)
852 FIXME("Set pCmdText\n");
853 }else if(IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
854 ULONG i;
856 for(i=0; i<cCmds; i++) {
857 switch(prgCmds[i].cmdID) {
858 case IDM_COPY:
859 FIXME("CGID_MSHTML: IDM_COPY\n");
860 prgCmds[i].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
861 break;
862 case IDM_CUT:
863 FIXME("CGID_MSHTML: IDM_CUT\n");
864 prgCmds[i].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
865 break;
866 case IDM_FONTNAME:
867 TRACE("CGID_MSHTML: IDM_FONTNAME\n");
868 prgCmds[i].cmdf = query_edit_status(This, NULL);
869 break;
870 case IDM_FONTSIZE:
871 TRACE("CGID_MSHTML: IDM_FONTSIZE\n");
872 prgCmds[i].cmdf = query_edit_status(This, NULL);
873 break;
874 case IDM_PRINT:
875 FIXME("CGID_MSHTML: IDM_PRINT\n");
876 prgCmds[i].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
877 break;
878 case IDM_PASTE:
879 FIXME("CGID_MSHTML: IDM_PASTE\n");
880 prgCmds[i].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
881 break;
882 case IDM_BOLD:
883 TRACE("CGID_MSHTML: IDM_BOLD\n");
884 prgCmds[i].cmdf = query_edit_status(This, NSCMD_BOLD);
885 break;
886 case IDM_FORECOLOR:
887 TRACE("CGID_MSHTML: IDM_FORECOLOR\n");
888 prgCmds[i].cmdf = query_edit_status(This, NULL);
889 break;
890 case IDM_ITALIC:
891 TRACE("CGID_MSHTML: IDM_ITALIC\n");
892 prgCmds[i].cmdf = query_edit_status(This, NSCMD_ITALIC);
893 break;
894 case IDM_JUSTIFYCENTER:
895 TRACE("CGID_MSHTML: IDM_JUSTIFYCENTER\n");
896 prgCmds[i].cmdf = query_align_status(This, NSALIGN_CENTER);
897 break;
898 case IDM_JUSTIFYLEFT:
899 TRACE("CGID_MSHTML: IDM_JUSTIFYLEFT\n");
900 prgCmds[i].cmdf = query_align_status(This, NSALIGN_LEFT);
901 break;
902 case IDM_JUSTIFYRIGHT:
903 TRACE("CGID_MSHTML: IDM_JUSTIFYRIGHT\n");
904 prgCmds[i].cmdf = query_align_status(This, NSALIGN_RIGHT);
905 break;
906 case IDM_UNDERLINE:
907 TRACE("CGID_MSHTML: IDM_UNDERLINE\n");
908 prgCmds[i].cmdf = query_edit_status(This, NSCMD_UNDERLINE);
909 break;
910 case IDM_HORIZONTALLINE:
911 TRACE("CGID_MSHTML: IDM_HORIZONTALLINE\n");
912 prgCmds[i].cmdf = query_edit_status(This, NULL);
913 break;
914 case IDM_ORDERLIST:
915 TRACE("CGID_MSHTML: IDM_ORDERLIST\n");
916 prgCmds[i].cmdf = query_edit_status(This, NSCMD_OL);
917 break;
918 case IDM_UNORDERLIST:
919 TRACE("CGID_MSHTML: IDM_HORIZONTALLINE\n");
920 prgCmds[i].cmdf = query_edit_status(This, NSCMD_UL);
921 break;
922 case IDM_INDENT:
923 TRACE("CGID_MSHTML: IDM_INDENT\n");
924 prgCmds[i].cmdf = query_edit_status(This, NULL);
925 break;
926 case IDM_OUTDENT:
927 TRACE("CGID_MSHTML: IDM_OUTDENT\n");
928 prgCmds[i].cmdf = query_edit_status(This, NULL);
929 break;
930 case IDM_BLOCKDIRLTR:
931 FIXME("CGID_MSHTML: IDM_BLOCKDIRLTR\n");
932 prgCmds[i].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
933 break;
934 case IDM_BLOCKDIRRTL:
935 FIXME("CGID_MSHTML: IDM_BLOCKDIRRTL\n");
936 prgCmds[i].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
937 break;
938 default:
939 FIXME("CGID_MSHTML: unsupported cmdID %d\n", prgCmds[i].cmdID);
940 prgCmds[i].cmdf = 0;
944 hres = prgCmds[i-1].cmdf ? S_OK : OLECMDERR_E_NOTSUPPORTED;
946 if(pCmdText)
947 FIXME("Set pCmdText\n");
948 }else {
949 FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup));
950 hres = OLECMDERR_E_UNKNOWNGROUP;
953 return hres;
956 static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
957 DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
959 HTMLDocument *This = CMDTARGET_THIS(iface);
961 if(!pguidCmdGroup) {
962 if(nCmdID<OLECMDID_OPEN || nCmdID>OLECMDID_GETPRINTTEMPLATE || !exec_table[nCmdID].func) {
963 WARN("Unsupported cmdID = %d\n", nCmdID);
964 return OLECMDERR_E_NOTSUPPORTED;
967 return exec_table[nCmdID].func(This, nCmdexecopt, pvaIn, pvaOut);
968 }else if(IsEqualGUID(&CGID_Explorer, pguidCmdGroup)) {
969 FIXME("unsupported nCmdID %d of CGID_Explorer group\n", nCmdID);
970 TRACE("%p %p\n", pvaIn, pvaOut);
971 return OLECMDERR_E_NOTSUPPORTED;
972 }else if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) {
973 FIXME("unsupported nCmdID %d of CGID_ShellDocView group\n", nCmdID);
974 return OLECMDERR_E_NOTSUPPORTED;
975 }else if(IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
976 switch(nCmdID) {
977 case IDM_FONTNAME:
978 return exec_fontname(This, pvaIn, pvaOut);
979 case IDM_FONTSIZE:
980 return exec_fontsize(This, pvaIn, pvaOut);
981 case IDM_PRINT:
982 return exec_print(This, nCmdexecopt, pvaIn, pvaOut);
983 case IDM_BOLD:
984 if(pvaIn || pvaOut)
985 FIXME("unsupported arguments\n");
986 return exec_bold(This);
987 case IDM_FORECOLOR:
988 return exec_forecolor(This, pvaIn, pvaOut);
989 case IDM_ITALIC:
990 if(pvaIn || pvaOut)
991 FIXME("unsupported arguments\n");
992 return exec_italic(This);
993 case IDM_JUSTIFYCENTER:
994 if(pvaIn || pvaOut)
995 FIXME("unsupported arguments\n");
996 return exec_justifycenter(This);
997 case IDM_JUSTIFYLEFT:
998 if(pvaIn || pvaOut)
999 FIXME("unsupported arguments\n");
1000 return exec_justifyleft(This);
1001 case IDM_JUSTIFYRIGHT:
1002 if(pvaIn || pvaOut)
1003 FIXME("unsupported arguments\n");
1004 return exec_justifyright(This);
1005 case IDM_UNDERLINE:
1006 if(pvaIn || pvaOut)
1007 FIXME("unsupported arguments\n");
1008 return exec_underline(This);
1009 case IDM_BROWSEMODE:
1010 if(pvaIn || pvaOut)
1011 FIXME("unsupported arguments\n");
1012 return exec_browsemode(This);
1013 case IDM_EDITMODE:
1014 if(pvaIn || pvaOut)
1015 FIXME("unsupported arguments\n");
1016 return exec_editmode(This);
1017 case IDM_BASELINEFONT3:
1018 return exec_baselinefont3(This);
1019 case IDM_HORIZONTALLINE:
1020 if(pvaIn || pvaOut)
1021 FIXME("unsupported arguments\n");
1022 return exec_horizontalline(This);
1023 case IDM_ORDERLIST:
1024 if(pvaIn || pvaOut)
1025 FIXME("unsupported arguments\n");
1026 return exec_orderlist(This);
1027 case IDM_UNORDERLIST:
1028 if(pvaIn || pvaOut)
1029 FIXME("unsupported arguments\n");
1030 return exec_unorderlist(This);
1031 case IDM_INDENT:
1032 if(pvaIn || pvaOut)
1033 FIXME("unsupported arguments\n");
1034 return exec_indent(This);
1035 case IDM_OUTDENT:
1036 if(pvaIn || pvaOut)
1037 FIXME("unsupported arguments\n");
1038 return exec_outdent(This);
1039 default:
1040 FIXME("unsupported nCmdID %d of CGID_MSHTML group\n", nCmdID);
1041 return OLECMDERR_E_NOTSUPPORTED;
1045 FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup));
1046 return OLECMDERR_E_UNKNOWNGROUP;
1049 #undef CMDTARGET_THIS
1051 static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
1052 OleCommandTarget_QueryInterface,
1053 OleCommandTarget_AddRef,
1054 OleCommandTarget_Release,
1055 OleCommandTarget_QueryStatus,
1056 OleCommandTarget_Exec
1059 void HTMLDocument_OleCmd_Init(HTMLDocument *This)
1061 This->lpOleCommandTargetVtbl = &OleCommandTargetVtbl;