2 * Copyright 2005-2007 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
32 #include "wine/debug.h"
34 #include "mshtml_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
40 #define NSCMD_COPY "cmd_copy"
41 #define NSCMD_SELECTALL "cmd_selectAll"
43 void do_ns_command(HTMLDocumentNode
*doc
, const char *cmd
, nsICommandParams
*nsparam
)
45 nsICommandManager
*cmdmgr
;
50 if(!doc
->browser
|| !doc
->window
)
53 nsres
= get_nsinterface((nsISupports
*)doc
->browser
->webbrowser
, &IID_nsICommandManager
, (void**)&cmdmgr
);
54 if(NS_FAILED(nsres
)) {
55 ERR("Could not get nsICommandManager: %08lx\n", nsres
);
59 nsres
= nsICommandManager_DoCommand(cmdmgr
, cmd
, nsparam
, doc
->window
->base
.outer_window
->window_proxy
);
61 ERR("DoCommand(%s) failed: %08lx\n", debugstr_a(cmd
), nsres
);
63 nsICommandManager_Release(cmdmgr
);
66 static nsIClipboardCommands
*get_clipboard_commands(HTMLDocumentNode
*doc
)
68 nsIClipboardCommands
*clipboard_commands
;
69 nsIDocShell
*doc_shell
;
75 nsres
= get_nsinterface((nsISupports
*)doc
->window
->dom_window
, &IID_nsIDocShell
, (void**)&doc_shell
);
76 if(NS_FAILED(nsres
)) {
77 ERR("Could not get nsIDocShell interface\n");
81 nsres
= nsIDocShell_QueryInterface(doc_shell
, &IID_nsIClipboardCommands
, (void**)&clipboard_commands
);
82 nsIDocShell_Release(doc_shell
);
83 if(NS_FAILED(nsres
)) {
84 ERR("Could not get nsIClipboardCommands interface\n");
88 return clipboard_commands
;
91 /**********************************************************
92 * IOleCommandTarget implementation
95 static inline HTMLDocumentNode
*HTMLDocumentNode_from_IOleCommandTarget(IOleCommandTarget
*iface
)
97 return CONTAINING_RECORD(iface
, HTMLDocumentNode
, IOleCommandTarget_iface
);
100 static inline HTMLDocumentObj
*HTMLDocumentObj_from_IOleCommandTarget(IOleCommandTarget
*iface
)
102 return CONTAINING_RECORD(iface
, HTMLDocumentObj
, IOleCommandTarget_iface
);
105 static HRESULT
exec_open(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
107 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
111 static HRESULT
exec_new(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
113 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
117 static HRESULT
exec_save(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
119 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
123 static HRESULT
exec_save_as(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
125 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
129 static HRESULT
exec_save_copy_as(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
131 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
135 static nsresult
set_head_text(nsIPrintSettings
*settings
, LPCWSTR
template, BOOL head
, int pos
)
140 return nsIPrintSettings_SetHeaderStrLeft(settings
, template);
142 return nsIPrintSettings_SetHeaderStrRight(settings
, template);
144 return nsIPrintSettings_SetHeaderStrCenter(settings
, template);
149 return nsIPrintSettings_SetFooterStrLeft(settings
, template);
151 return nsIPrintSettings_SetFooterStrRight(settings
, template);
153 return nsIPrintSettings_SetFooterStrCenter(settings
, template);
160 static void set_print_template(nsIPrintSettings
*settings
, LPCWSTR
template, BOOL head
)
162 PRUnichar nstemplate
[200]; /* FIXME: Use dynamic allocation */
163 PRUnichar
*p
= nstemplate
;
164 LPCWSTR ptr
=template;
179 case 'b': /* change align */
182 set_head_text(settings
, nstemplate
, head
, pos
);
186 case 'd': { /* short date */
188 GetLocalTime(&systime
);
189 GetDateFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &systime
, NULL
, p
,
190 sizeof(nstemplate
)-(p
-nstemplate
)*sizeof(WCHAR
));
195 case 'p': /* page number */
200 case 'P': /* page count */
201 *p
++ = '?'; /* FIXME */
210 /* FIXME: set window title */
220 set_head_text(settings
, nstemplate
, head
, pos
);
223 set_head_text(settings
, p
, head
, pos
);
226 static void set_default_templates(nsIPrintSettings
*settings
)
230 nsIPrintSettings_SetHeaderStrLeft(settings
, L
"");
231 nsIPrintSettings_SetHeaderStrRight(settings
, L
"");
232 nsIPrintSettings_SetHeaderStrCenter(settings
, L
"");
233 nsIPrintSettings_SetFooterStrLeft(settings
, L
"");
234 nsIPrintSettings_SetFooterStrRight(settings
, L
"");
235 nsIPrintSettings_SetFooterStrCenter(settings
, L
"");
237 if(LoadStringW(get_shdoclc(), IDS_PRINT_HEADER_TEMPLATE
, buf
, ARRAY_SIZE(buf
)))
238 set_print_template(settings
, buf
, TRUE
);
240 if(LoadStringW(get_shdoclc(), IDS_PRINT_FOOTER_TEMPLATE
, buf
, ARRAY_SIZE(buf
)))
241 set_print_template(settings
, buf
, FALSE
);
245 static HRESULT
exec_print(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
247 nsIWebBrowserPrint
*nsprint
;
248 nsIPrintSettings
*settings
;
251 TRACE("(%p)->(%ld %s %p)\n", doc
, nCmdexecopt
, debugstr_variant(pvaIn
), pvaOut
);
254 FIXME("unsupported pvaOut\n");
256 nsres
= get_nsinterface((nsISupports
*)doc
->browser
->webbrowser
, &IID_nsIWebBrowserPrint
,
258 if(NS_FAILED(nsres
)) {
259 ERR("Could not get nsIWebBrowserPrint: %08lx\n", nsres
);
263 nsres
= nsIWebBrowserPrint_GetGlobalPrintSettings(nsprint
, &settings
);
265 ERR("GetCurrentPrintSettings failed: %08lx\n", nsres
);
267 set_default_templates(settings
);
270 switch(V_VT(pvaIn
)) {
271 case VT_BYREF
|VT_ARRAY
: {
275 if(V_ARRAY(pvaIn
)->cDims
!= 1)
276 WARN("cDims = %d\n", V_ARRAY(pvaIn
)->cDims
);
278 SafeArrayAccessData(V_ARRAY(pvaIn
), (void**)&opts
);
279 opts_cnt
= V_ARRAY(pvaIn
)->rgsabound
[0].cElements
;
284 TRACE("setting footer %s\n", debugstr_w(V_BSTR(opts
)));
285 set_print_template(settings
, V_BSTR(opts
), TRUE
);
290 WARN("opts = %s\n", debugstr_variant(opts
));
295 switch(V_VT(opts
+1)) {
297 TRACE("setting footer %s\n", debugstr_w(V_BSTR(opts
+1)));
298 set_print_template(settings
, V_BSTR(opts
+1), FALSE
);
303 WARN("opts[1] = %s\n", debugstr_variant(opts
+1));
308 FIXME("Unsupported opts_cnt %ld\n", opts_cnt
);
310 SafeArrayUnaccessData(V_ARRAY(pvaIn
));
314 FIXME("unsupported arg %s\n", debugstr_variant(pvaIn
));
318 nsres
= nsIWebBrowserPrint_Print(nsprint
, settings
, NULL
);
320 ERR("Print failed: %08lx\n", nsres
);
322 nsIWebBrowserPrint_Release(nsprint
);
327 static HRESULT
exec_print_preview(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
329 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
333 static HRESULT
exec_page_setup(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
335 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
339 static HRESULT
exec_spell(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
341 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
345 static HRESULT
exec_properties(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
347 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
351 static HRESULT
exec_cut(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
353 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
357 static HRESULT
exec_copy(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
359 TRACE("(%p)->(%ld %s %p)\n", doc
, nCmdexecopt
, debugstr_variant(pvaIn
), pvaOut
);
361 do_ns_command(doc
, NSCMD_COPY
, NULL
);
365 static HRESULT
exec_paste(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
367 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
371 static HRESULT
exec_paste_special(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
373 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
377 static HRESULT
exec_undo(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
379 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
383 static HRESULT
exec_rendo(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
385 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
389 static HRESULT
exec_select_all(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*in
, VARIANT
*out
)
391 TRACE("(%p)\n", doc
);
394 FIXME("unsupported args\n");
399 do_ns_command(doc
, NSCMD_SELECTALL
, NULL
);
400 update_doc(doc
->browser
->doc
, UPDATE_UI
);
404 static HRESULT
exec_clear_selection(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
406 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
410 static HRESULT
exec_zoom(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
412 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
416 static HRESULT
exec_get_zoom_range(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
418 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
424 HTMLOuterWindow
*window
;
427 static void refresh_proc(task_t
*_task
)
429 refresh_task_t
*task
= (refresh_task_t
*)_task
;
430 HTMLOuterWindow
*window
= task
->window
;
432 TRACE("%p\n", window
);
434 window
->readystate
= READYSTATE_UNINITIALIZED
;
436 if(window
->browser
&& window
->browser
->doc
->client_cmdtrg
) {
441 IOleCommandTarget_Exec(window
->browser
->doc
->client_cmdtrg
, &CGID_ShellDocView
, 37, 0, &var
, NULL
);
444 load_uri(window
, window
->uri
, BINDING_REFRESH
|BINDING_NOFRAG
);
447 static void refresh_destr(task_t
*_task
)
449 refresh_task_t
*task
= (refresh_task_t
*)_task
;
451 IHTMLWindow2_Release(&task
->window
->base
.IHTMLWindow2_iface
);
454 HRESULT
reload_page(HTMLOuterWindow
*window
)
456 refresh_task_t
*task
;
458 task
= malloc(sizeof(*task
));
460 return E_OUTOFMEMORY
;
462 IHTMLWindow2_AddRef(&window
->base
.IHTMLWindow2_iface
);
463 task
->window
= window
;
465 return push_task(&task
->header
, refresh_proc
, refresh_destr
, window
->task_magic
);
468 static HRESULT
exec_refresh(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
470 HTMLDocumentObj
*doc_obj
;
473 TRACE("(%p)->(%ld %s %p)\n", doc
, nCmdexecopt
, debugstr_variant(pvaIn
), pvaOut
);
475 if(doc
!= doc
->browser
->doc
->doc_node
) {
476 FIXME("Unsupported on frame documents\n");
479 doc_obj
= doc
->browser
->doc
;
481 if(doc_obj
->client
) {
482 IOleCommandTarget
*olecmd
;
484 hres
= IOleClientSite_QueryInterface(doc_obj
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
485 if(SUCCEEDED(hres
)) {
486 hres
= IOleCommandTarget_Exec(olecmd
, &CGID_DocHostCommandHandler
, 2300, nCmdexecopt
, pvaIn
, pvaOut
);
487 IOleCommandTarget_Release(olecmd
);
493 if(!doc
->window
|| !doc
->window
->base
.outer_window
)
496 return reload_page(doc
->window
->base
.outer_window
);
499 static HRESULT
exec_stop(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
501 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
505 static HRESULT
exec_stop_download(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
507 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
511 static HRESULT
exec_find(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
513 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
517 static HRESULT
exec_delete(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
519 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
523 static HRESULT
exec_enable_interaction(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
525 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
529 static HRESULT
exec_on_unload(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
531 TRACE("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
533 /* Tests show that we have nothing more to do here */
536 V_VT(pvaOut
) = VT_BOOL
;
537 V_BOOL(pvaOut
) = VARIANT_TRUE
;
543 static HRESULT
exec_show_page_setup(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
545 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
549 static HRESULT
exec_show_print(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
551 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
555 static HRESULT
exec_close(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
557 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
561 static HRESULT
exec_set_print_template(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
563 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
567 static HRESULT
exec_get_print_template(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
569 FIXME("(%p)->(%ld %p %p)\n", doc
, nCmdexecopt
, pvaIn
, pvaOut
);
573 static HRESULT
exec_optical_zoom(HTMLDocumentNode
*doc
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
575 TRACE("(%p)->(%ld %s %p)\n", doc
, nCmdexecopt
, debugstr_variant(pvaIn
), pvaOut
);
577 if(pvaIn
&& V_VT(pvaIn
) != VT_I4
) {
578 FIXME("Unsupported argument %s\n", debugstr_variant(pvaIn
));
583 set_viewer_zoom(doc
->browser
, (float)V_I4(pvaIn
)/100);
585 V_VT(pvaOut
) = VT_I4
;
586 V_I4(pvaOut
) = get_viewer_zoom(doc
->browser
) * 100;
591 static HRESULT
query_mshtml_copy(HTMLDocumentNode
*doc
, OLECMD
*cmd
)
593 FIXME("(%p)\n", doc
);
594 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
598 static HRESULT
exec_mshtml_copy(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
600 TRACE("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
602 if(doc
->browser
->usermode
== EDITMODE
)
603 return editor_exec_copy(doc
, cmdexecopt
, in
, out
);
605 do_ns_command(doc
, NSCMD_COPY
, NULL
);
609 static HRESULT
query_mshtml_cut(HTMLDocumentNode
*doc
, OLECMD
*cmd
)
611 FIXME("(%p)\n", doc
);
612 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
616 static HRESULT
exec_mshtml_cut(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
618 nsIClipboardCommands
*clipboard_commands
;
621 TRACE("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
623 if(doc
->browser
->usermode
== EDITMODE
)
624 return editor_exec_cut(doc
, cmdexecopt
, in
, out
);
626 clipboard_commands
= get_clipboard_commands(doc
);
627 if(!clipboard_commands
)
630 nsres
= nsIClipboardCommands_CutSelection(clipboard_commands
);
631 nsIClipboardCommands_Release(clipboard_commands
);
632 if(NS_FAILED(nsres
)) {
633 ERR("Paste failed: %08lx\n", nsres
);
640 static HRESULT
query_mshtml_paste(HTMLDocumentNode
*doc
, OLECMD
*cmd
)
642 FIXME("(%p)\n", doc
);
643 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
647 static HRESULT
exec_mshtml_paste(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
649 nsIClipboardCommands
*clipboard_commands
;
652 TRACE("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
654 if(doc
->browser
->usermode
== EDITMODE
)
655 return editor_exec_paste(doc
, cmdexecopt
, in
, out
);
657 clipboard_commands
= get_clipboard_commands(doc
);
658 if(!clipboard_commands
)
661 nsres
= nsIClipboardCommands_Paste(clipboard_commands
);
662 nsIClipboardCommands_Release(clipboard_commands
);
663 if(NS_FAILED(nsres
)) {
664 ERR("Paste failed: %08lx\n", nsres
);
671 static HRESULT
query_selall_status(HTMLDocumentNode
*doc
, OLECMD
*cmd
)
673 TRACE("(%p)->(%p)\n", doc
, cmd
);
675 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
679 static HRESULT
exec_browsemode(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
681 WARN("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
684 FIXME("unsupported args\n");
686 doc
->browser
->usermode
= BROWSEMODE
;
691 static HRESULT
exec_editmode(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
693 HTMLDocumentObj
*doc_obj
;
696 TRACE("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
699 FIXME("unsupported args\n");
701 doc_obj
= doc
->browser
->doc
;
702 IUnknown_AddRef(doc_obj
->outer_unk
);
703 hres
= setup_edit_mode(doc_obj
);
704 IUnknown_Release(doc_obj
->outer_unk
);
708 static HRESULT
exec_htmleditmode(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
710 FIXME("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
714 static HRESULT
exec_baselinefont3(HTMLDocumentNode
*doc
, DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
716 FIXME("(%p)->(%08lx %p %p)\n", doc
, cmdexecopt
, in
, out
);
720 static HRESULT
exec_respectvisibility_indesign(HTMLDocumentNode
*doc
, DWORD cmdexecopt
,
721 VARIANT
*in
, VARIANT
*out
)
723 TRACE("(%p)->(%lx %s %p)\n", doc
, cmdexecopt
, debugstr_variant(in
), out
);
725 /* This is turned on by default in Gecko. */
726 if(!in
|| V_VT(in
) != VT_BOOL
|| !V_BOOL(in
))
727 FIXME("Unsupported argument %s\n", debugstr_variant(in
));
732 static HRESULT
query_enabled_stub(HTMLDocumentNode
*doc
, OLECMD
*cmd
)
736 FIXME("CGID_MSHTML: IDM_PRINT\n");
737 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
739 case IDM_BLOCKDIRLTR
:
740 FIXME("CGID_MSHTML: IDM_BLOCKDIRLTR\n");
741 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
743 case IDM_BLOCKDIRRTL
:
744 FIXME("CGID_MSHTML: IDM_BLOCKDIRRTL\n");
745 cmd
->cmdf
= OLECMDF_SUPPORTED
|OLECMDF_ENABLED
;
752 static const struct {
754 HRESULT (*func
)(HTMLDocumentNode
*,DWORD
,VARIANT
*,VARIANT
*);
757 { OLECMDF_SUPPORTED
, exec_open
}, /* OLECMDID_OPEN */
758 { OLECMDF_SUPPORTED
, exec_new
}, /* OLECMDID_NEW */
759 { OLECMDF_SUPPORTED
, exec_save
}, /* OLECMDID_SAVE */
760 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_save_as
}, /* OLECMDID_SAVEAS */
761 { OLECMDF_SUPPORTED
, exec_save_copy_as
}, /* OLECMDID_SAVECOPYAS */
762 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_print
}, /* OLECMDID_PRINT */
763 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_print_preview
}, /* OLECMDID_PRINTPREVIEW */
764 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_page_setup
}, /* OLECMDID_PAGESETUP */
765 { OLECMDF_SUPPORTED
, exec_spell
}, /* OLECMDID_SPELL */
766 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_properties
}, /* OLECMDID_PROPERTIES */
767 { OLECMDF_SUPPORTED
, exec_cut
}, /* OLECMDID_CUT */
768 { OLECMDF_SUPPORTED
, exec_copy
}, /* OLECMDID_COPY */
769 { OLECMDF_SUPPORTED
, exec_paste
}, /* OLECMDID_PASTE */
770 { OLECMDF_SUPPORTED
, exec_paste_special
}, /* OLECMDID_PASTESPECIAL */
771 { OLECMDF_SUPPORTED
, exec_undo
}, /* OLECMDID_UNDO */
772 { OLECMDF_SUPPORTED
, exec_rendo
}, /* OLECMDID_REDO */
773 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_select_all
}, /* OLECMDID_SELECTALL */
774 { OLECMDF_SUPPORTED
, exec_clear_selection
}, /* OLECMDID_CLEARSELECTION */
775 { OLECMDF_SUPPORTED
, exec_zoom
}, /* OLECMDID_ZOOM */
776 { OLECMDF_SUPPORTED
, exec_get_zoom_range
}, /* OLECMDID_GETZOOMRANGE */
778 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_refresh
}, /* OLECMDID_REFRESH */
779 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_stop
}, /* OLECMDID_STOP */
780 {0},{0},{0},{0},{0},{0},
781 { OLECMDF_SUPPORTED
, exec_stop_download
}, /* OLECMDID_STOPDOWNLOAD */
783 { OLECMDF_SUPPORTED
|OLECMDF_ENABLED
, exec_find
}, /* OLECMDID_FIND */
784 { OLECMDF_SUPPORTED
, exec_delete
}, /* OLECMDID_DELETE */
786 { OLECMDF_SUPPORTED
, exec_enable_interaction
}, /* OLECMDID_ENABLE_INTERACTION */
787 { OLECMDF_SUPPORTED
, exec_on_unload
}, /* OLECMDID_ONUNLOAD */
789 { OLECMDF_SUPPORTED
, exec_show_page_setup
}, /* OLECMDID_SHOWPAGESETUP */
790 { OLECMDF_SUPPORTED
, exec_show_print
}, /* OLECMDID_SHOWPRINT */
792 { OLECMDF_SUPPORTED
, exec_close
}, /* OLECMDID_CLOSE */
794 { OLECMDF_SUPPORTED
, exec_set_print_template
}, /* OLECMDID_SETPRINTTEMPLATE */
795 { OLECMDF_SUPPORTED
, exec_get_print_template
}, /* OLECMDID_GETPRINTTEMPLATE */
796 {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},
797 { 0, /* not reported as supported */ exec_optical_zoom
} /* OLECMDID_OPTICAL_ZOOM */
800 static const cmdtable_t base_cmds
[] = {
801 {IDM_COPY
, query_mshtml_copy
, exec_mshtml_copy
},
802 {IDM_PASTE
, query_mshtml_paste
, exec_mshtml_paste
},
803 {IDM_CUT
, query_mshtml_cut
, exec_mshtml_cut
},
804 {IDM_SELECTALL
, query_selall_status
, exec_select_all
},
805 {IDM_BROWSEMODE
, NULL
, exec_browsemode
},
806 {IDM_EDITMODE
, NULL
, exec_editmode
},
807 {IDM_PRINT
, query_enabled_stub
, exec_print
},
808 {IDM_HTMLEDITMODE
, NULL
, exec_htmleditmode
},
809 {IDM_BASELINEFONT3
, NULL
, exec_baselinefont3
},
810 {IDM_BLOCKDIRLTR
, query_enabled_stub
, NULL
},
811 {IDM_BLOCKDIRRTL
, query_enabled_stub
, NULL
},
812 {IDM_RESPECTVISIBILITY_INDESIGN
, NULL
, exec_respectvisibility_indesign
},
816 static HRESULT WINAPI
DocNodeOleCommandTarget_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppv
)
818 HTMLDocumentNode
*This
= HTMLDocumentNode_from_IOleCommandTarget(iface
);
819 return IHTMLDOMNode_QueryInterface(&This
->node
.IHTMLDOMNode_iface
, riid
, ppv
);
822 static ULONG WINAPI
DocNodeOleCommandTarget_AddRef(IOleCommandTarget
*iface
)
824 HTMLDocumentNode
*This
= HTMLDocumentNode_from_IOleCommandTarget(iface
);
825 return IHTMLDOMNode_AddRef(&This
->node
.IHTMLDOMNode_iface
);
828 static ULONG WINAPI
DocNodeOleCommandTarget_Release(IOleCommandTarget
*iface
)
830 HTMLDocumentNode
*This
= HTMLDocumentNode_from_IOleCommandTarget(iface
);
831 return IHTMLDOMNode_Release(&This
->node
.IHTMLDOMNode_iface
);
834 static HRESULT
query_from_table(HTMLDocumentNode
*doc
, const cmdtable_t
*cmdtable
, OLECMD
*cmd
)
836 const cmdtable_t
*iter
= cmdtable
;
840 while(iter
->id
&& iter
->id
!= cmd
->cmdID
)
843 if(!iter
->id
|| !iter
->query
)
844 return OLECMDERR_E_NOTSUPPORTED
;
846 return iter
->query(doc
, cmd
);
849 static HRESULT WINAPI
DocNodeOleCommandTarget_QueryStatus(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
850 ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
852 HTMLDocumentNode
*This
= HTMLDocumentNode_from_IOleCommandTarget(iface
);
855 TRACE("(%p)->(%s %ld %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
858 FIXME("Unsupported pCmdText\n");
867 for(i
=0; i
<cCmds
; i
++) {
868 if(prgCmds
[i
].cmdID
< OLECMDID_OPEN
|| prgCmds
[i
].cmdID
>= ARRAY_SIZE(exec_table
)) {
869 WARN("Unsupported cmdID = %ld\n", prgCmds
[i
].cmdID
);
872 if(prgCmds
[i
].cmdID
== OLECMDID_OPEN
|| prgCmds
[i
].cmdID
== OLECMDID_NEW
) {
873 IOleCommandTarget
*cmdtrg
= NULL
;
876 prgCmds
[i
].cmdf
= OLECMDF_SUPPORTED
;
877 if(This
->doc_obj
->client
) {
878 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
880 if(SUCCEEDED(hres
)) {
881 olecmd
.cmdID
= prgCmds
[i
].cmdID
;
884 hres
= IOleCommandTarget_QueryStatus(cmdtrg
, NULL
, 1, &olecmd
, NULL
);
885 if(SUCCEEDED(hres
) && olecmd
.cmdf
)
886 prgCmds
[i
].cmdf
= olecmd
.cmdf
;
889 ERR("This->client == NULL, native would crash\n");
892 prgCmds
[i
].cmdf
= exec_table
[prgCmds
[i
].cmdID
].cmdf
;
893 TRACE("cmdID = %ld returning %lx\n", prgCmds
[i
].cmdID
, prgCmds
[i
].cmdf
);
898 return (prgCmds
[cCmds
-1].cmdf
& OLECMDF_SUPPORTED
) ? S_OK
: OLECMDERR_E_NOTSUPPORTED
;
901 if(IsEqualGUID(&CGID_MSHTML
, pguidCmdGroup
)) {
904 for(i
=0; i
<cCmds
; i
++) {
905 hres
= query_from_table(This
, base_cmds
, prgCmds
+i
);
906 if(hres
== OLECMDERR_E_NOTSUPPORTED
)
907 hres
= query_from_table(This
, editmode_cmds
, prgCmds
+i
);
908 if(hres
== OLECMDERR_E_NOTSUPPORTED
)
909 FIXME("CGID_MSHTML: unsupported cmdID %ld\n", prgCmds
[i
].cmdID
);
912 return (prgCmds
[cCmds
-1].cmdf
& OLECMDF_SUPPORTED
) ? S_OK
: OLECMDERR_E_NOTSUPPORTED
;
915 FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup
));
916 return OLECMDERR_E_UNKNOWNGROUP
;
919 static HRESULT
exec_from_table(HTMLDocumentNode
*doc
, const cmdtable_t
*cmdtable
, DWORD cmdid
,
920 DWORD cmdexecopt
, VARIANT
*in
, VARIANT
*out
)
922 const cmdtable_t
*iter
= cmdtable
;
924 while(iter
->id
&& iter
->id
!= cmdid
)
927 if(!iter
->id
|| !iter
->exec
)
928 return OLECMDERR_E_NOTSUPPORTED
;
930 return iter
->exec(doc
, cmdexecopt
, in
, out
);
933 static HRESULT WINAPI
DocNodeOleCommandTarget_Exec(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
934 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
936 HTMLDocumentNode
*This
= HTMLDocumentNode_from_IOleCommandTarget(iface
);
938 TRACE("(%p)->(%s %ld %ld %s %p)\n", This
, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, wine_dbgstr_variant(pvaIn
), pvaOut
);
944 if(nCmdID
< OLECMDID_OPEN
|| nCmdID
>= ARRAY_SIZE(exec_table
) || !exec_table
[nCmdID
].func
) {
945 WARN("Unsupported cmdID = %ld\n", nCmdID
);
946 return OLECMDERR_E_NOTSUPPORTED
;
949 return exec_table
[nCmdID
].func(This
, nCmdexecopt
, pvaIn
, pvaOut
);
950 }else if(IsEqualGUID(&CGID_Explorer
, pguidCmdGroup
)) {
951 FIXME("unsupported nCmdID %ld of CGID_Explorer group\n", nCmdID
);
952 TRACE("%p %p\n", pvaIn
, pvaOut
);
953 return OLECMDERR_E_NOTSUPPORTED
;
954 }else if(IsEqualGUID(&CGID_ShellDocView
, pguidCmdGroup
)) {
955 FIXME("unsupported nCmdID %ld of CGID_ShellDocView group\n", nCmdID
);
956 return OLECMDERR_E_NOTSUPPORTED
;
957 }else if(IsEqualGUID(&CGID_MSHTML
, pguidCmdGroup
)) {
958 HRESULT hres
= exec_from_table(This
, base_cmds
, nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
959 if(hres
== OLECMDERR_E_NOTSUPPORTED
)
960 hres
= exec_from_table(This
, editmode_cmds
, nCmdID
,
961 nCmdexecopt
, pvaIn
, pvaOut
);
962 if(hres
== OLECMDERR_E_NOTSUPPORTED
)
963 FIXME("unsupported nCmdID %ld of CGID_MSHTML group\n", nCmdID
);
968 FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup
));
969 return OLECMDERR_E_UNKNOWNGROUP
;
972 static const IOleCommandTargetVtbl DocNodeOleCommandTargetVtbl
= {
973 DocNodeOleCommandTarget_QueryInterface
,
974 DocNodeOleCommandTarget_AddRef
,
975 DocNodeOleCommandTarget_Release
,
976 DocNodeOleCommandTarget_QueryStatus
,
977 DocNodeOleCommandTarget_Exec
980 static HRESULT WINAPI
DocObjOleCommandTarget_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppv
)
982 HTMLDocumentObj
*This
= HTMLDocumentObj_from_IOleCommandTarget(iface
);
983 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
986 static ULONG WINAPI
DocObjOleCommandTarget_AddRef(IOleCommandTarget
*iface
)
988 HTMLDocumentObj
*This
= HTMLDocumentObj_from_IOleCommandTarget(iface
);
989 return IUnknown_AddRef(This
->outer_unk
);
992 static ULONG WINAPI
DocObjOleCommandTarget_Release(IOleCommandTarget
*iface
)
994 HTMLDocumentObj
*This
= HTMLDocumentObj_from_IOleCommandTarget(iface
);
995 return IUnknown_Release(This
->outer_unk
);
998 static HRESULT WINAPI
DocObjOleCommandTarget_QueryStatus(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
999 ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
1001 HTMLDocumentObj
*This
= HTMLDocumentObj_from_IOleCommandTarget(iface
);
1003 return IOleCommandTarget_QueryStatus(&This
->doc_node
->IOleCommandTarget_iface
,
1004 pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
1007 static HRESULT WINAPI
DocObjOleCommandTarget_Exec(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1008 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1010 HTMLDocumentObj
*This
= HTMLDocumentObj_from_IOleCommandTarget(iface
);
1012 return IOleCommandTarget_Exec(&This
->doc_node
->IOleCommandTarget_iface
,
1013 pguidCmdGroup
, nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
1016 static const IOleCommandTargetVtbl DocObjOleCommandTargetVtbl
= {
1017 DocObjOleCommandTarget_QueryInterface
,
1018 DocObjOleCommandTarget_AddRef
,
1019 DocObjOleCommandTarget_Release
,
1020 DocObjOleCommandTarget_QueryStatus
,
1021 DocObjOleCommandTarget_Exec
1024 void show_context_menu(HTMLDocumentObj
*This
, DWORD dwID
, POINT
*ppt
, IDispatch
*elem
)
1026 HMENU menu_res
, menu
;
1029 if(This
->hostui
&& S_OK
== IDocHostUIHandler_ShowContextMenu(This
->hostui
,
1030 dwID
, ppt
, (IUnknown
*)&This
->IOleCommandTarget_iface
, elem
))
1033 menu_res
= LoadMenuW(get_shdoclc(), MAKEINTRESOURCEW(IDR_BROWSE_CONTEXT_MENU
));
1034 menu
= GetSubMenu(menu_res
, dwID
);
1036 cmdid
= TrackPopupMenu(menu
, TPM_LEFTALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1037 ppt
->x
, ppt
->y
, 0, This
->hwnd
, NULL
);
1038 DestroyMenu(menu_res
);
1041 IOleCommandTarget_Exec(&This
->IOleCommandTarget_iface
, &CGID_MSHTML
, cmdid
, 0,
1045 void HTMLDocumentNode_OleCmd_Init(HTMLDocumentNode
*This
)
1047 This
->IOleCommandTarget_iface
.lpVtbl
= &DocNodeOleCommandTargetVtbl
;
1050 void HTMLDocumentObj_OleCmd_Init(HTMLDocumentObj
*This
)
1052 This
->IOleCommandTarget_iface
.lpVtbl
= &DocObjOleCommandTargetVtbl
;