ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

editor.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2007 Jacek Caban for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include <stdarg.h>
00020 #include <stdio.h>
00021 
00022 #define COBJMACROS
00023 
00024 #include "windef.h"
00025 #include "winbase.h"
00026 #include "winuser.h"
00027 #include "ole2.h"
00028 #include "mshtmcid.h"
00029 
00030 #include "wine/debug.h"
00031 #include "wine/unicode.h"
00032 
00033 #include "mshtml_private.h"
00034 #include "resource.h"
00035 
00036 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
00037 
00038 #define NSCMD_ALIGN        "cmd_align"
00039 #define NSCMD_BEGINLINE    "cmd_beginLine"
00040 #define NSCMD_BOLD         "cmd_bold"
00041 #define NSCMD_CHARNEXT     "cmd_charNext"
00042 #define NSCMD_CHARPREVIOUS "cmd_charPrevious"
00043 #define NSCMD_COPY         "cmd_copy"
00044 #define NSCMD_CUT          "cmd_cut"
00045 #define NSCMD_DELETECHARFORWARD   "cmd_deleteCharForward"
00046 #define NSCMD_DELETEWORDFORWARD   "cmd_deleteWordForward"
00047 #define NSCMD_ENDLINE      "cmd_endLine"
00048 #define NSCMD_FONTCOLOR    "cmd_fontColor"
00049 #define NSCMD_FONTFACE     "cmd_fontFace"
00050 #define NSCMD_INDENT       "cmd_indent"
00051 #define NSCMD_INSERTHR     "cmd_insertHR"
00052 #define NSCMD_INSERTLINKNOUI    "cmd_insertLinkNoUI"
00053 #define NSCMD_ITALIC       "cmd_italic"
00054 #define NSCMD_LINENEXT     "cmd_lineNext"
00055 #define NSCMD_LINEPREVIOUS "cmd_linePrevious"
00056 #define NSCMD_MOVEBOTTOM   "cmd_moveBottom"
00057 #define NSCMD_MOVEPAGEDOWN "cmd_movePageDown"
00058 #define NSCMD_MOVEPAGEUP   "cmd_movePageUp"
00059 #define NSCMD_MOVETOP      "cmd_moveTop"
00060 #define NSCMD_OL           "cmd_ol"
00061 #define NSCMD_OUTDENT      "cmd_outdent"
00062 #define NSCMD_PASTE        "cmd_paste"
00063 #define NSCMD_SELECTALL           "cmd_selectAll"
00064 #define NSCMD_SELECTBEGINLINE     "cmd_selectBeginLine"
00065 #define NSCMD_SELECTBOTTOM        "cmd_selectBottom"
00066 #define NSCMD_SELECTCHARNEXT      "cmd_selectCharNext"
00067 #define NSCMD_SELECTCHARPREVIOUS  "cmd_selectCharPrevious"
00068 #define NSCMD_SELECTENDLINE       "cmd_selectEndLine"
00069 #define NSCMD_SELECTLINENEXT      "cmd_selectLineNext"
00070 #define NSCMD_SELECTLINEPREVIOUS  "cmd_selectLinePrevious"
00071 #define NSCMD_SELECTPAGEDOWN      "cmd_selectPageDown"
00072 #define NSCMD_SELECTPAGEUP        "cmd_selectPageUp"
00073 #define NSCMD_SELECTTOP           "cmd_selectTop"
00074 #define NSCMD_SELECTWORDNEXT      "cmd_selectWordNext"
00075 #define NSCMD_SELECTWORDPREVIOUS  "cmd_selectWordPrevious"
00076 #define NSCMD_UL           "cmd_ul"
00077 #define NSCMD_UNDERLINE    "cmd_underline"
00078 #define NSCMD_WORDNEXT     "cmd_wordNext"
00079 #define NSCMD_WORDPREVIOUS "cmd_wordPrevious"
00080 
00081 #define NSSTATE_ATTRIBUTE "state_attribute"
00082 #define NSSTATE_ALL       "state_all"
00083 
00084 #define NSALIGN_CENTER "center"
00085 #define NSALIGN_LEFT   "left"
00086 #define NSALIGN_RIGHT  "right"
00087 
00088 #define DOM_VK_LEFT     VK_LEFT
00089 #define DOM_VK_UP       VK_UP
00090 #define DOM_VK_RIGHT    VK_RIGHT
00091 #define DOM_VK_DOWN     VK_DOWN
00092 #define DOM_VK_DELETE   VK_DELETE
00093 #define DOM_VK_HOME     VK_HOME
00094 #define DOM_VK_END      VK_END
00095 
00096 static const WCHAR fontW[] = {'f','o','n','t',0};
00097 static const WCHAR sizeW[] = {'s','i','z','e',0};
00098 
00099 void set_dirty(HTMLDocument *This, VARIANT_BOOL dirty)
00100 {
00101     nsresult nsres;
00102 
00103     if(This->doc_obj->usermode != EDITMODE || !This->doc_obj->nscontainer || !This->doc_obj->nscontainer->editor)
00104         return;
00105 
00106     if(dirty) {
00107         nsres = nsIEditor_IncrementModificationCount(This->doc_obj->nscontainer->editor, 1);
00108         if(NS_FAILED(nsres))
00109             ERR("IncrementModificationCount failed: %08x\n", nsres);
00110     }else {
00111         nsres = nsIEditor_ResetModificationCount(This->doc_obj->nscontainer->editor);
00112         if(NS_FAILED(nsres))
00113             ERR("ResetModificationCount failed: %08x\n", nsres);
00114     }
00115 }
00116 
00117 static void do_ns_editor_command(NSContainer *This, const char *cmd)
00118 {
00119     nsresult nsres;
00120 
00121     if(!This->editor_controller)
00122         return;
00123 
00124     nsres = nsIController_DoCommand(This->editor_controller, cmd);
00125     if(NS_FAILED(nsres))
00126         ERR("DoCommand(%s) failed: %08x\n", debugstr_a(cmd), nsres);
00127 }
00128 
00129 static nsresult get_ns_command_state(NSContainer *This, const char *cmd, nsICommandParams *nsparam)
00130 {
00131     nsICommandManager *cmdmgr;
00132     nsresult nsres;
00133 
00134     nsres = get_nsinterface((nsISupports*)This->webbrowser, &IID_nsICommandManager, (void**)&cmdmgr);
00135     if(NS_FAILED(nsres)) {
00136         ERR("Could not get nsICommandManager: %08x\n", nsres);
00137         return nsres;
00138     }
00139 
00140     nsres = nsICommandManager_GetCommandState(cmdmgr, cmd, This->doc->basedoc.window->nswindow, nsparam);
00141     if(NS_FAILED(nsres))
00142         ERR("GetCommandState(%s) failed: %08x\n", debugstr_a(cmd), nsres);
00143 
00144     nsICommandManager_Release(cmdmgr);
00145     return nsres;
00146 }
00147 
00148 static DWORD query_ns_edit_status(HTMLDocument *This, const char *nscmd)
00149 {
00150     nsICommandParams *nsparam;
00151     PRBool b = FALSE;
00152 
00153     if(This->doc_obj->usermode != EDITMODE || This->window->readystate < READYSTATE_INTERACTIVE)
00154         return OLECMDF_SUPPORTED;
00155 
00156     if(This->doc_obj->nscontainer && nscmd) {
00157         nsparam = create_nscommand_params();
00158         get_ns_command_state(This->doc_obj->nscontainer, nscmd, nsparam);
00159 
00160         nsICommandParams_GetBooleanValue(nsparam, NSSTATE_ALL, &b);
00161 
00162         nsICommandParams_Release(nsparam);
00163     }
00164 
00165     return OLECMDF_SUPPORTED | OLECMDF_ENABLED | (b ? OLECMDF_LATCHED : 0);
00166 }
00167 
00168 static void set_ns_align(HTMLDocument *This, const char *align_str)
00169 {
00170     nsICommandParams *nsparam;
00171 
00172     if(!This->doc_obj->nscontainer)
00173         return;
00174 
00175     nsparam = create_nscommand_params();
00176     nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, align_str);
00177 
00178     do_ns_command(This, NSCMD_ALIGN, nsparam);
00179 
00180     nsICommandParams_Release(nsparam);
00181 }
00182 
00183 static DWORD query_align_status(HTMLDocument *This, const char *align_str)
00184 {
00185     nsICommandParams *nsparam;
00186     char *align = NULL;
00187 
00188     if(This->doc_obj->usermode != EDITMODE || This->window->readystate < READYSTATE_INTERACTIVE)
00189         return OLECMDF_SUPPORTED;
00190 
00191     if(This->doc_obj->nscontainer) {
00192         nsparam = create_nscommand_params();
00193         get_ns_command_state(This->doc_obj->nscontainer, NSCMD_ALIGN, nsparam);
00194 
00195         nsICommandParams_GetCStringValue(nsparam, NSSTATE_ATTRIBUTE, &align);
00196 
00197         nsICommandParams_Release(nsparam);
00198     }
00199 
00200     return OLECMDF_SUPPORTED | OLECMDF_ENABLED
00201         | (align && !strcmp(align_str, align) ? OLECMDF_LATCHED : 0);
00202 }
00203 
00204 
00205 static nsISelection *get_ns_selection(HTMLDocument *This)
00206 {
00207     nsISelection *nsselection = NULL;
00208     nsresult nsres;
00209 
00210     nsres = nsIDOMWindow_GetSelection(This->window->nswindow, &nsselection);
00211     if(NS_FAILED(nsres))
00212         ERR("GetSelection failed %08x\n", nsres);
00213 
00214     return nsselection;
00215 
00216 }
00217 
00218 static void remove_child_attr(nsIDOMElement *elem, LPCWSTR tag, nsAString *attr_str)
00219 {
00220     PRBool has_children;
00221     PRUint32 child_cnt, i;
00222     nsIDOMNode *child_node;
00223     nsIDOMNodeList *node_list;
00224     PRUint16 node_type;
00225 
00226     nsIDOMElement_HasChildNodes(elem, &has_children);
00227     if(!has_children)
00228         return;
00229 
00230     nsIDOMElement_GetChildNodes(elem, &node_list);
00231     nsIDOMNodeList_GetLength(node_list, &child_cnt);
00232 
00233     for(i=0; i<child_cnt; i++) {
00234         nsIDOMNodeList_Item(node_list, i, &child_node);
00235 
00236         nsIDOMNode_GetNodeType(child_node, &node_type);
00237         if(node_type == ELEMENT_NODE) {
00238             nsIDOMElement *child_elem;
00239             nsAString tag_str;
00240             const PRUnichar *ctag;
00241 
00242             nsIDOMNode_QueryInterface(child_node, &IID_nsIDOMElement, (void**)&child_elem);
00243 
00244             nsAString_Init(&tag_str, NULL);
00245             nsIDOMElement_GetTagName(child_elem, &tag_str);
00246             nsAString_GetData(&tag_str, &ctag);
00247 
00248             if(!strcmpiW(ctag, tag))
00249                 /* FIXME: remove node if there are no more attributes */
00250                 nsIDOMElement_RemoveAttribute(child_elem, attr_str);
00251 
00252             nsAString_Finish(&tag_str);
00253 
00254             remove_child_attr(child_elem, tag, attr_str);
00255 
00256             nsIDOMNode_Release(child_elem);
00257         }
00258 
00259         nsIDOMNode_Release(child_node);
00260     }
00261 
00262     nsIDOMNodeList_Release(node_list);
00263 }
00264 
00265 static void get_font_size(HTMLDocument *This, WCHAR *ret)
00266 {
00267     nsISelection *nsselection = get_ns_selection(This);
00268     nsIDOMElement *elem = NULL;
00269     nsIDOMNode *node = NULL, *tmp_node;
00270     nsAString tag_str;
00271     LPCWSTR tag;
00272     PRUint16 node_type;
00273     nsresult nsres;
00274 
00275     *ret = 0;
00276 
00277     if(!nsselection)
00278         return;
00279 
00280     nsISelection_GetFocusNode(nsselection, &node);
00281     nsISelection_Release(nsselection);
00282 
00283     while(node) {
00284         nsres = nsIDOMNode_GetNodeType(node, &node_type);
00285         if(NS_FAILED(nsres) || node_type == DOCUMENT_NODE)
00286             break;
00287 
00288         if(node_type == ELEMENT_NODE) {
00289             nsIDOMNode_QueryInterface(node, &IID_nsIDOMElement, (void**)&elem);
00290 
00291             nsAString_Init(&tag_str, NULL);
00292             nsIDOMElement_GetTagName(elem, &tag_str);
00293             nsAString_GetData(&tag_str, &tag);
00294 
00295             if(!strcmpiW(tag, fontW)) {
00296                 nsAString size_str, val_str;
00297                 LPCWSTR val;
00298 
00299                 TRACE("found font tag %p\n", elem);
00300 
00301                 nsAString_InitDepend(&size_str, sizeW);
00302                 nsAString_Init(&val_str, NULL);
00303 
00304                 nsIDOMElement_GetAttribute(elem, &size_str, &val_str);
00305                 nsAString_GetData(&val_str, &val);
00306 
00307                 if(*val) {
00308                     TRACE("found size %s\n", debugstr_w(val));
00309                     strcpyW(ret, val);
00310                 }
00311 
00312                 nsAString_Finish(&size_str);
00313                 nsAString_Finish(&val_str);
00314             }
00315 
00316             nsAString_Finish(&tag_str);
00317 
00318             nsIDOMElement_Release(elem);
00319         }
00320 
00321         if(*ret)
00322             break;
00323 
00324         tmp_node = node;
00325         nsIDOMNode_GetParentNode(node, &node);
00326         nsIDOMNode_Release(tmp_node);
00327     }
00328 
00329     if(node)
00330         nsIDOMNode_Release(node);
00331 }
00332 
00333 static void set_font_size(HTMLDocument *This, LPCWSTR size)
00334 {
00335     nsISelection *nsselection;
00336     PRBool collapsed;
00337     nsIDOMHTMLElement *elem;
00338     nsIDOMRange *range;
00339     PRInt32 range_cnt = 0;
00340     nsAString size_str;
00341     nsAString val_str;
00342 
00343     if(!This->doc_node->nsdoc) {
00344         WARN("NULL nsdoc\n");
00345         return;
00346     }
00347 
00348     nsselection = get_ns_selection(This);
00349     if(!nsselection)
00350         return;
00351 
00352     nsISelection_GetRangeCount(nsselection, &range_cnt);
00353     if(range_cnt != 1) {
00354         FIXME("range_cnt %d not supprted\n", range_cnt);
00355         if(!range_cnt) {
00356             nsISelection_Release(nsselection);
00357             return;
00358         }
00359     }
00360 
00361     create_nselem(This->doc_node, fontW, &elem);
00362 
00363     nsAString_InitDepend(&size_str, sizeW);
00364     nsAString_InitDepend(&val_str, size);
00365 
00366     nsIDOMElement_SetAttribute(elem, &size_str, &val_str);
00367     nsAString_Finish(&val_str);
00368 
00369     nsISelection_GetRangeAt(nsselection, 0, &range);
00370     nsISelection_GetIsCollapsed(nsselection, &collapsed);
00371     nsISelection_RemoveAllRanges(nsselection);
00372 
00373     nsIDOMRange_SurroundContents(range, (nsIDOMNode*)elem);
00374 
00375     if(collapsed) {
00376         nsISelection_Collapse(nsselection, (nsIDOMNode*)elem, 0);
00377     }else {
00378         /* Remove all size attributes from the range */
00379         remove_child_attr((nsIDOMElement*)elem, fontW, &size_str);
00380         nsISelection_SelectAllChildren(nsselection, (nsIDOMNode*)elem);
00381     }
00382 
00383     nsISelection_Release(nsselection);
00384     nsIDOMRange_Release(range);
00385     nsIDOMElement_Release(elem);
00386 
00387     nsAString_Finish(&size_str);
00388 
00389     set_dirty(This, VARIANT_TRUE);
00390 }
00391 
00392 static void handle_arrow_key(HTMLDocument *This, nsIDOMKeyEvent *event, const char * const cmds[4])
00393 {
00394     int i=0;
00395     PRBool b;
00396 
00397     nsIDOMKeyEvent_GetCtrlKey(event, &b);
00398     if(b)
00399         i |= 1;
00400 
00401     nsIDOMKeyEvent_GetShiftKey(event, &b);
00402     if(b)
00403         i |= 2;
00404 
00405     if(cmds[i])
00406         do_ns_editor_command(This->doc_obj->nscontainer, cmds[i]);
00407 
00408     nsIDOMKeyEvent_PreventDefault(event);
00409 }
00410 
00411 void handle_edit_event(HTMLDocument *This, nsIDOMEvent *event)
00412 {
00413     nsIDOMKeyEvent *key_event;
00414     PRUint32 code;
00415 
00416     nsIDOMEvent_QueryInterface(event, &IID_nsIDOMKeyEvent, (void**)&key_event);
00417 
00418     nsIDOMKeyEvent_GetKeyCode(key_event, &code);
00419 
00420     switch(code) {
00421     case DOM_VK_LEFT: {
00422         static const char * const cmds[] = {
00423             NSCMD_CHARPREVIOUS,
00424             NSCMD_WORDPREVIOUS,
00425             NSCMD_SELECTCHARPREVIOUS,
00426             NSCMD_SELECTWORDPREVIOUS
00427         };
00428 
00429         TRACE("left\n");
00430         handle_arrow_key(This, key_event, cmds);
00431         break;
00432     }
00433     case DOM_VK_RIGHT: {
00434         static const char * const cmds[] = {
00435             NSCMD_CHARNEXT,
00436             NSCMD_WORDNEXT,
00437             NSCMD_SELECTCHARNEXT,
00438             NSCMD_SELECTWORDNEXT
00439         };
00440 
00441         TRACE("right\n");
00442         handle_arrow_key(This, key_event, cmds);
00443         break;
00444     }
00445     case DOM_VK_UP: {
00446         static const char * const cmds[] = {
00447             NSCMD_LINEPREVIOUS,
00448             NSCMD_MOVEPAGEUP,
00449             NSCMD_SELECTLINEPREVIOUS,
00450             NSCMD_SELECTPAGEUP
00451         };
00452 
00453         TRACE("up\n");
00454         handle_arrow_key(This, key_event, cmds);
00455         break;
00456     }
00457     case DOM_VK_DOWN: {
00458         static const char * const cmds[] = {
00459             NSCMD_LINENEXT,
00460             NSCMD_MOVEPAGEDOWN,
00461             NSCMD_SELECTLINENEXT,
00462             NSCMD_SELECTPAGEDOWN
00463         };
00464 
00465         TRACE("down\n");
00466         handle_arrow_key(This, key_event, cmds);
00467         break;
00468     }
00469     case DOM_VK_DELETE: {
00470         static const char * const cmds[] = {
00471             NSCMD_DELETECHARFORWARD,
00472             NSCMD_DELETEWORDFORWARD,
00473             NULL, NULL
00474         };
00475 
00476         TRACE("delete\n");
00477         handle_arrow_key(This, key_event, cmds);
00478         break;
00479     }
00480     case DOM_VK_HOME: {
00481         static const char * const cmds[] = {
00482             NSCMD_BEGINLINE,
00483             NSCMD_MOVETOP,
00484             NSCMD_SELECTBEGINLINE,
00485             NSCMD_SELECTTOP
00486         };
00487 
00488         TRACE("home\n");
00489         handle_arrow_key(This, key_event, cmds);
00490         break;
00491     }
00492     case DOM_VK_END: {
00493         static const char * const cmds[] = {
00494             NSCMD_ENDLINE,
00495             NSCMD_MOVEBOTTOM,
00496             NSCMD_SELECTENDLINE,
00497             NSCMD_SELECTBOTTOM
00498         };
00499 
00500         TRACE("end\n");
00501         handle_arrow_key(This, key_event, cmds);
00502         break;
00503     }
00504     }
00505 
00506     nsIDOMKeyEvent_Release(key_event);
00507 }
00508 
00509 void handle_edit_load(HTMLDocument *This)
00510 {
00511     get_editor_controller(This->doc_obj->nscontainer);
00512 }
00513 
00514 static void set_ns_fontname(HTMLDocument *This, const char *fontname)
00515 {
00516     nsICommandParams *nsparam = create_nscommand_params();
00517 
00518     nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, fontname);
00519     do_ns_command(This, NSCMD_FONTFACE, nsparam);
00520     nsICommandParams_Release(nsparam);
00521 }
00522 
00523 static HRESULT exec_delete(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00524 {
00525     TRACE("(%p)->(%p %p)\n", This, in, out);
00526 
00527     if(This->doc_obj->nscontainer)
00528         do_ns_editor_command(This->doc_obj->nscontainer, NSCMD_DELETECHARFORWARD);
00529 
00530     update_doc(This, UPDATE_UI);
00531     return S_OK;
00532 }
00533 
00534 static HRESULT exec_fontname(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00535 {
00536     TRACE("(%p)->(%p %p)\n", This, in, out);
00537 
00538     if(!This->doc_obj->nscontainer) {
00539         update_doc(This, UPDATE_UI);
00540         return E_FAIL;
00541     }
00542 
00543     if(in) {
00544         char *stra;
00545 
00546         if(V_VT(in) != VT_BSTR) {
00547             FIXME("Unsupported vt=%d\n", V_VT(out));
00548             return E_INVALIDARG;
00549         }
00550 
00551         TRACE("%s\n", debugstr_w(V_BSTR(in)));
00552 
00553         stra = heap_strdupWtoA(V_BSTR(in));
00554         set_ns_fontname(This, stra);
00555         heap_free(stra);
00556 
00557         update_doc(This, UPDATE_UI);
00558     }
00559 
00560     if(out) {
00561         nsICommandParams *nsparam;
00562         LPWSTR strw;
00563         char *stra;
00564         DWORD len;
00565         nsresult nsres;
00566 
00567         V_VT(out) = VT_BSTR;
00568         V_BSTR(out) = NULL;
00569 
00570         nsparam = create_nscommand_params();
00571 
00572         nsres = get_ns_command_state(This->doc_obj->nscontainer, NSCMD_FONTFACE, nsparam);
00573         if(NS_FAILED(nsres))
00574             return S_OK;
00575 
00576         nsICommandParams_GetCStringValue(nsparam, NSSTATE_ATTRIBUTE, &stra);
00577         nsICommandParams_Release(nsparam);
00578 
00579         len = MultiByteToWideChar(CP_ACP, 0, stra, -1, NULL, 0);
00580         strw = heap_alloc(len*sizeof(WCHAR));
00581         MultiByteToWideChar(CP_ACP, 0, stra, -1, strw, len);
00582         nsfree(stra);
00583 
00584         V_BSTR(out) = SysAllocString(strw);
00585         heap_free(strw);
00586     }
00587 
00588     return S_OK;
00589 }
00590 
00591 static HRESULT exec_forecolor(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00592 {
00593     TRACE("(%p)->(%p %p)\n", This, in, out);
00594 
00595     if(in) {
00596         if(V_VT(in) == VT_I4) {
00597             nsICommandParams *nsparam = create_nscommand_params();
00598             char color_str[10];
00599 
00600             sprintf(color_str, "#%02x%02x%02x",
00601                     V_I4(in)&0xff, (V_I4(in)>>8)&0xff, (V_I4(in)>>16)&0xff);
00602 
00603             nsICommandParams_SetCStringValue(nsparam, NSSTATE_ATTRIBUTE, color_str);
00604             do_ns_command(This, NSCMD_FONTCOLOR, nsparam);
00605 
00606             nsICommandParams_Release(nsparam);
00607         }else {
00608             FIXME("unsupported in vt=%d\n", V_VT(in));
00609         }
00610 
00611         update_doc(This, UPDATE_UI);
00612     }
00613 
00614     if(out) {
00615         FIXME("unsupported out\n");
00616         return E_NOTIMPL;
00617     }
00618 
00619     return S_OK;
00620 }
00621 
00622 static HRESULT exec_fontsize(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00623 {
00624     TRACE("(%p)->(%p %p)\n", This, in, out);
00625 
00626     if(out) {
00627         WCHAR val[10] = {0};
00628 
00629         get_font_size(This, val);
00630         V_VT(out) = VT_I4;
00631         V_I4(out) = strtolW(val, NULL, 10);
00632     }
00633 
00634     if(in) {
00635         switch(V_VT(in)) {
00636         case VT_I4: {
00637             WCHAR size[10];
00638             static const WCHAR format[] = {'%','d',0};
00639             wsprintfW(size, format, V_I4(in));
00640             set_font_size(This, size);
00641             break;
00642         }
00643         case VT_BSTR:
00644             set_font_size(This, V_BSTR(in));
00645             break;
00646         default:
00647             FIXME("unsupported vt %d\n", V_VT(in));
00648         }
00649 
00650         update_doc(This, UPDATE_UI);
00651     }
00652 
00653     return S_OK;
00654 }
00655 
00656 static HRESULT exec_font(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00657 {
00658 
00659     FIXME("(%p)->(%p %p)\n", This, in, out);
00660     return E_NOTIMPL;
00661 }
00662 
00663 static HRESULT exec_selectall(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00664 {
00665     TRACE("(%p)\n", This);
00666 
00667     if(in || out)
00668         FIXME("unsupported args\n");
00669 
00670     if(This->doc_obj->nscontainer)
00671         do_ns_command(This, NSCMD_SELECTALL, NULL);
00672 
00673     update_doc(This, UPDATE_UI);
00674     return S_OK;
00675 }
00676 
00677 static HRESULT exec_bold(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00678 {
00679     TRACE("(%p)\n", This);
00680 
00681     if(in || out)
00682         FIXME("unsupported args\n");
00683 
00684     if(This->doc_obj->nscontainer)
00685         do_ns_command(This, NSCMD_BOLD, NULL);
00686 
00687     update_doc(This, UPDATE_UI);
00688     return S_OK;
00689 }
00690 
00691 static HRESULT exec_italic(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00692 {
00693     TRACE("(%p)\n", This);
00694 
00695     if(in || out)
00696         FIXME("unsupported args\n");
00697 
00698     if(This->doc_obj->nscontainer)
00699         do_ns_command(This, NSCMD_ITALIC, NULL);
00700 
00701     update_doc(This, UPDATE_UI);
00702     return S_OK;
00703 }
00704 
00705 static HRESULT query_justify(HTMLDocument *This, OLECMD *cmd)
00706 {
00707     switch(cmd->cmdID) {
00708     case IDM_JUSTIFYCENTER:
00709         TRACE("(%p) IDM_JUSTIFYCENTER\n", This);
00710         cmd->cmdf = query_align_status(This, NSALIGN_CENTER);
00711         break;
00712     case IDM_JUSTIFYLEFT:
00713         TRACE("(%p) IDM_JUSTIFYLEFT\n", This);
00714         /* FIXME: We should set OLECMDF_LATCHED only if it's set explicitly. */
00715         if(This->doc_obj->usermode != EDITMODE || This->window->readystate < READYSTATE_INTERACTIVE)
00716             cmd->cmdf = OLECMDF_SUPPORTED;
00717         else
00718             cmd->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
00719         break;
00720     case IDM_JUSTIFYRIGHT:
00721         TRACE("(%p) IDM_JUSTIFYRIGHT\n", This);
00722         cmd->cmdf = query_align_status(This, NSALIGN_RIGHT);
00723         break;
00724     }
00725 
00726     return S_OK;
00727 }
00728 
00729 static HRESULT exec_justifycenter(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00730 {
00731     TRACE("(%p)\n", This);
00732 
00733     if(in || out)
00734         FIXME("unsupported args\n");
00735 
00736     set_ns_align(This, NSALIGN_CENTER);
00737     update_doc(This, UPDATE_UI);
00738     return S_OK;
00739 }
00740 
00741 static HRESULT exec_justifyleft(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00742 {
00743     TRACE("(%p)\n", This);
00744 
00745     if(in || out)
00746         FIXME("unsupported args\n");
00747 
00748     set_ns_align(This, NSALIGN_LEFT);
00749     update_doc(This, UPDATE_UI);
00750     return S_OK;
00751 }
00752 
00753 static HRESULT exec_justifyright(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00754 {
00755     TRACE("(%p)\n", This);
00756 
00757     if(in || out)
00758         FIXME("unsupported args\n");
00759 
00760     set_ns_align(This, NSALIGN_RIGHT);
00761     update_doc(This, UPDATE_UI);
00762     return S_OK;
00763 }
00764 
00765 static HRESULT exec_underline(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00766 {
00767     TRACE("(%p)\n", This);
00768 
00769     if(in || out)
00770         FIXME("unsupported args\n");
00771 
00772     do_ns_command(This, NSCMD_UNDERLINE, NULL);
00773     update_doc(This, UPDATE_UI);
00774     return S_OK;
00775 }
00776 
00777 static HRESULT exec_horizontalline(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00778 {
00779     TRACE("(%p)\n", This);
00780 
00781     if(in || out)
00782         FIXME("unsupported args\n");
00783 
00784     do_ns_command(This, NSCMD_INSERTHR, NULL);
00785     update_doc(This, UPDATE_UI);
00786     return S_OK;
00787 }
00788 
00789 static HRESULT exec_orderlist(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00790 {
00791     TRACE("(%p)\n", This);
00792 
00793     if(in || out)
00794         FIXME("unsupported args\n");
00795 
00796     do_ns_command(This, NSCMD_OL, NULL);
00797     update_doc(This, UPDATE_UI);
00798     return S_OK;
00799 }
00800 
00801 static HRESULT exec_unorderlist(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00802 {
00803     TRACE("(%p)\n", This);
00804 
00805     if(in || out)
00806         FIXME("unsupported args\n");
00807 
00808     do_ns_command(This, NSCMD_UL, NULL);
00809     update_doc(This, UPDATE_UI);
00810     return S_OK;
00811 }
00812 
00813 static HRESULT exec_indent(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00814 {
00815     TRACE("(%p)\n", This);
00816 
00817     if(in || out)
00818         FIXME("unsupported args\n");
00819 
00820     do_ns_command(This, NSCMD_INDENT, NULL);
00821     update_doc(This, UPDATE_UI);
00822     return S_OK;
00823 }
00824 
00825 static HRESULT exec_outdent(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00826 {
00827     TRACE("(%p)\n", This);
00828 
00829     if(in || out)
00830         FIXME("unsupported args\n");
00831 
00832     do_ns_command(This, NSCMD_OUTDENT, NULL);
00833     update_doc(This, UPDATE_UI);
00834     return S_OK;
00835 }
00836 
00837 static HRESULT exec_composesettings(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00838 {
00839     WCHAR *ptr;
00840 
00841     if(out || !in || V_VT(in) != VT_BSTR) {
00842         WARN("invalid arg\n");
00843         return E_INVALIDARG;
00844     }
00845 
00846     TRACE("(%p)->(%x %s)\n", This, cmdexecopt, debugstr_w(V_BSTR(in)));
00847 
00848     update_doc(This, UPDATE_UI);
00849 
00850     ptr = V_BSTR(in);
00851     if(*ptr == '1')
00852         exec_bold(This, cmdexecopt, NULL, NULL);
00853     ptr = strchrW(ptr, ',');
00854     if(!ptr)
00855         return S_OK;
00856 
00857     if(*++ptr == '1')
00858         exec_italic(This, cmdexecopt, NULL, NULL);
00859     ptr = strchrW(ptr, ',');
00860     if(!ptr)
00861         return S_OK;
00862 
00863     if(*++ptr == '1')
00864         exec_underline(This, cmdexecopt, NULL, NULL);
00865     ptr = strchrW(ptr, ',');
00866     if(!ptr)
00867         return S_OK;
00868 
00869     if(isdigitW(*++ptr)) {
00870         VARIANT v;
00871 
00872         V_VT(&v) = VT_I4;
00873         V_I4(&v) = *ptr-'0';
00874 
00875         exec_fontsize(This, cmdexecopt, &v, NULL);
00876     }
00877     ptr = strchrW(ptr, ',');
00878     if(!ptr)
00879         return S_OK;
00880 
00881     if(*++ptr != ',')
00882         FIXME("set font color\n");
00883     ptr = strchrW(ptr, ',');
00884     if(!ptr)
00885         return S_OK;
00886 
00887     if(*++ptr != ',')
00888         FIXME("set background color\n");
00889     ptr = strchrW(ptr, ',');
00890     if(!ptr)
00891         return S_OK;
00892 
00893     ptr++;
00894     if(*ptr) {
00895         VARIANT v;
00896 
00897         V_VT(&v) = VT_BSTR;
00898         V_BSTR(&v) = SysAllocString(ptr);
00899 
00900         exec_fontname(This, cmdexecopt, &v, NULL);
00901 
00902         SysFreeString(V_BSTR(&v));
00903     }
00904 
00905     return S_OK;
00906 }
00907 
00908 HRESULT editor_exec_copy(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00909 {
00910     update_doc(This, UPDATE_UI);
00911 
00912     if(!This->doc_obj->nscontainer)
00913         return E_FAIL;
00914 
00915     do_ns_editor_command(This->doc_obj->nscontainer, NSCMD_COPY);
00916     return S_OK;
00917 }
00918 
00919 HRESULT editor_exec_cut(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00920 {
00921     update_doc(This, UPDATE_UI);
00922 
00923     if(!This->doc_obj->nscontainer)
00924         return E_FAIL;
00925 
00926     do_ns_editor_command(This->doc_obj->nscontainer, NSCMD_CUT);
00927     return S_OK;
00928 }
00929 
00930 HRESULT editor_exec_paste(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00931 {
00932     update_doc(This, UPDATE_UI);
00933 
00934     if(!This->doc_obj->nscontainer)
00935         return E_FAIL;
00936 
00937     do_ns_editor_command(This->doc_obj->nscontainer, NSCMD_PASTE);
00938     return S_OK;
00939 }
00940 
00941 static HRESULT exec_setdirty(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
00942 {
00943     TRACE("(%p)->(%08x %p %p)\n", This, cmdexecopt, in, out);
00944 
00945     if(!in)
00946         return S_OK;
00947 
00948     if(V_VT(in) == VT_BOOL)
00949         set_dirty(This, V_BOOL(in));
00950     else
00951         FIXME("unsupported vt=%d\n", V_VT(in));
00952 
00953     return S_OK;
00954 }
00955 
00956 static HRESULT query_edit_status(HTMLDocument *This, OLECMD *cmd)
00957 {
00958     switch(cmd->cmdID) {
00959     case IDM_DELETE:
00960         TRACE("CGID_MSHTML: IDM_DELETE\n");
00961         cmd->cmdf = query_ns_edit_status(This, NULL);
00962         break;
00963     case IDM_FONTNAME:
00964         TRACE("CGID_MSHTML: IDM_FONTNAME\n");
00965         cmd->cmdf = query_ns_edit_status(This, NULL);
00966         break;
00967     case IDM_FONTSIZE:
00968         TRACE("CGID_MSHTML: IDM_FONTSIZE\n");
00969         cmd->cmdf = query_ns_edit_status(This, NULL);
00970         break;
00971     case IDM_BOLD:
00972         TRACE("CGID_MSHTML: IDM_BOLD\n");
00973         cmd->cmdf = query_ns_edit_status(This, NSCMD_BOLD);
00974         break;
00975     case IDM_FORECOLOR:
00976         TRACE("CGID_MSHTML: IDM_FORECOLOR\n");
00977         cmd->cmdf = query_ns_edit_status(This, NULL);
00978         break;
00979     case IDM_ITALIC:
00980         TRACE("CGID_MSHTML: IDM_ITALIC\n");
00981         cmd->cmdf = query_ns_edit_status(This, NSCMD_ITALIC);
00982         break;
00983     case IDM_UNDERLINE:
00984         TRACE("CGID_MSHTML: IDM_UNDERLINE\n");
00985         cmd->cmdf = query_ns_edit_status(This, NSCMD_UNDERLINE);
00986         break;
00987     case IDM_HORIZONTALLINE:
00988         TRACE("CGID_MSHTML: IDM_HORIZONTALLINE\n");
00989         cmd->cmdf = query_ns_edit_status(This, NULL);
00990         break;
00991     case IDM_ORDERLIST:
00992         TRACE("CGID_MSHTML: IDM_ORDERLIST\n");
00993         cmd->cmdf = query_ns_edit_status(This, NSCMD_OL);
00994         break;
00995     case IDM_UNORDERLIST:
00996         TRACE("CGID_MSHTML: IDM_HORIZONTALLINE\n");
00997         cmd->cmdf = query_ns_edit_status(This, NSCMD_UL);
00998         break;
00999     case IDM_INDENT:
01000         TRACE("CGID_MSHTML: IDM_INDENT\n");
01001         cmd->cmdf = query_ns_edit_status(This, NULL);
01002         break;
01003     case IDM_OUTDENT:
01004         TRACE("CGID_MSHTML: IDM_OUTDENT\n");
01005         cmd->cmdf = query_ns_edit_status(This, NULL);
01006         break;
01007     case IDM_HYPERLINK:
01008         TRACE("CGID_MSHTML: IDM_HYPERLINK\n");
01009         cmd->cmdf = query_ns_edit_status(This, NULL);
01010         break;
01011     }
01012 
01013     return S_OK;
01014 }
01015 
01016 static INT_PTR CALLBACK hyperlink_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
01017 {
01018     static const WCHAR wszOther[] = {'(','o','t','h','e','r',')',0};
01019 
01020     switch (msg)
01021     {
01022         case WM_INITDIALOG:
01023         {
01024             static const WCHAR wszFile[] = {'f','i','l','e',':',0};
01025             static const WCHAR wszFtp[] = {'f','t','p',':',0};
01026             static const WCHAR wszHttp[] = {'h','t','t','p',':',0};
01027             static const WCHAR wszHttps[] = {'h','t','t','p','s',':',0};
01028             static const WCHAR wszMailto[] = {'m','a','i','l','t','o',':',0};
01029             static const WCHAR wszNews[] = {'n','e','w','s',':',0};
01030             INT def_idx;
01031             HWND hwndCB = GetDlgItem(hwnd, IDC_TYPE);
01032             HWND hwndURL = GetDlgItem(hwnd, IDC_URL);
01033             INT len;
01034 
01035             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
01036 
01037             SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszOther);
01038             SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszFile);
01039             SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszFtp);
01040             def_idx = SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszHttp);
01041             SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszHttps);
01042             SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszMailto);
01043             SendMessageW(hwndCB, CB_INSERTSTRING, -1, (LPARAM)wszNews);
01044             SendMessageW(hwndCB, CB_SETCURSEL, def_idx, 0);
01045 
01046             /* force the updating of the URL edit box */
01047             SendMessageW(hwnd, WM_COMMAND, MAKEWPARAM(IDC_TYPE, CBN_SELCHANGE), (LPARAM)hwndCB);
01048 
01049             SetFocus(hwndURL);
01050             len = SendMessageW(hwndURL, WM_GETTEXTLENGTH, 0, 0);
01051             SendMessageW(hwndURL, EM_SETSEL, 0, len);
01052 
01053             return FALSE;
01054         }
01055         case WM_COMMAND:
01056             switch (wparam)
01057             {
01058                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
01059                     EndDialog(hwnd, wparam);
01060                     return TRUE;
01061                 case MAKEWPARAM(IDOK, BN_CLICKED):
01062                 {
01063                     BSTR *url = (BSTR *)GetWindowLongPtrW(hwnd, DWLP_USER);
01064                     HWND hwndURL = GetDlgItem(hwnd, IDC_URL);
01065                     INT len = GetWindowTextLengthW(hwndURL);
01066                     *url = SysAllocStringLen(NULL, len + 1);
01067                     GetWindowTextW(hwndURL, *url, len + 1);
01068                     EndDialog(hwnd, wparam);
01069                     return TRUE;
01070                 }
01071                 case MAKEWPARAM(IDC_TYPE, CBN_SELCHANGE):
01072                 {
01073                     HWND hwndURL = GetDlgItem(hwnd, IDC_URL);
01074                     INT item;
01075                     INT len;
01076                     LPWSTR type;
01077                     LPWSTR url;
01078                     LPWSTR p;
01079                     static const WCHAR wszSlashSlash[] = {'/','/'};
01080 
01081                     /* get string of currently selected hyperlink type */
01082                     item = SendMessageW((HWND)lparam, CB_GETCURSEL, 0, 0);
01083                     len = SendMessageW((HWND)lparam, CB_GETLBTEXTLEN, item, 0);
01084                     type = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
01085                     SendMessageW((HWND)lparam, CB_GETLBTEXT, item, (LPARAM)type);
01086 
01087                     if (!strcmpW(type, wszOther))
01088                         *type = '\0';
01089 
01090                     /* get current URL */
01091                     len = GetWindowTextLengthW(hwndURL);
01092                     url = HeapAlloc(GetProcessHeap(), 0, (len + strlenW(type) + 3) * sizeof(WCHAR));
01093                     GetWindowTextW(hwndURL, url, len + 1);
01094 
01095                     /* strip off old protocol */
01096                     p = strchrW(url, ':');
01097                     if (p && p[1] == '/' && p[2] == '/')
01098                         p += 3;
01099                     if (!p) p = url;
01100                     memmove(url + (*type != '\0' ? strlenW(type) + 2 : 0), p, (len + 1 - (p - url)) * sizeof(WCHAR));
01101 
01102                     /* add new protocol */
01103                     if (*type != '\0')
01104                     {
01105                         memcpy(url, type, strlenW(type) * sizeof(WCHAR));
01106                         memcpy(url + strlenW(type), wszSlashSlash, sizeof(wszSlashSlash));
01107                     }
01108 
01109                     SetWindowTextW(hwndURL, url);
01110 
01111                     HeapFree(GetProcessHeap(), 0, url);
01112                     HeapFree(GetProcessHeap(), 0, type);
01113                     return TRUE;
01114                 }
01115             }
01116             return FALSE;
01117         case WM_CLOSE:
01118             EndDialog(hwnd, IDCANCEL);
01119             return TRUE;
01120         default:
01121             return FALSE;
01122     }
01123 }
01124 
01125 static HRESULT exec_hyperlink(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out)
01126 {
01127     nsAString href_str, ns_url;
01128     nsIHTMLEditor *html_editor;
01129     nsIDOMHTMLElement *anchor_elem;
01130     PRBool insert_link_at_caret;
01131     nsISelection *nsselection;
01132     BSTR url = NULL;
01133     INT ret;
01134     HRESULT hres = E_FAIL;
01135 
01136     static const WCHAR aW[] = {'a',0};
01137     static const WCHAR hrefW[] = {'h','r','e','f',0};
01138 
01139     TRACE("%p, 0x%x, %p, %p\n", This, cmdexecopt, in, out);
01140 
01141     if (cmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER)
01142     {
01143         if (!in || V_VT(in) != VT_BSTR)
01144         {
01145             WARN("invalid arg\n");
01146             return E_INVALIDARG;
01147         }
01148         url = V_BSTR(in);
01149     }
01150     else
01151     {
01152         ret = DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_HYPERLINK), NULL /* FIXME */, hyperlink_dlgproc, (LPARAM)&url);
01153         if (ret != IDOK)
01154             return OLECMDERR_E_CANCELED;
01155     }
01156 
01157     if(!This->doc_node->nsdoc) {
01158         WARN("NULL nsdoc\n");
01159         return E_UNEXPECTED;
01160     }
01161 
01162     nsselection = get_ns_selection(This);
01163     if (!nsselection)
01164         return E_FAIL;
01165 
01166     /* create an element for the link */
01167     create_nselem(This->doc_node, aW, &anchor_elem);
01168 
01169     nsAString_InitDepend(&href_str, hrefW);
01170     nsAString_InitDepend(&ns_url, url);
01171     nsIDOMElement_SetAttribute(anchor_elem, &href_str, &ns_url);
01172     nsAString_Finish(&href_str);
01173 
01174     nsISelection_GetIsCollapsed(nsselection, &insert_link_at_caret);
01175 
01176     /* create an element with text of URL */
01177     if (insert_link_at_caret) {
01178         nsIDOMNode *text_node, *unused_node;
01179 
01180         nsIDOMDocument_CreateTextNode(This->doc_node->nsdoc, &ns_url, (nsIDOMText **)&text_node);
01181 
01182         /* wrap the <a> tags around the text element */
01183         nsIDOMElement_AppendChild(anchor_elem, text_node, &unused_node);
01184         nsIDOMNode_Release(text_node);
01185         nsIDOMNode_Release(unused_node);
01186     }
01187 
01188     nsAString_Finish(&ns_url);
01189 
01190     nsIEditor_QueryInterface(This->doc_obj->nscontainer->editor, &IID_nsIHTMLEditor, (void **)&html_editor);
01191     if (html_editor) {
01192         nsresult nsres;
01193 
01194         if (insert_link_at_caret) {
01195             /* add them to the document at the caret position */
01196             nsres = nsIHTMLEditor_InsertElementAtSelection(html_editor, (nsIDOMElement*)anchor_elem, FALSE);
01197             nsISelection_SelectAllChildren(nsselection, (nsIDOMNode*)anchor_elem);
01198         }else /* add them around the selection using the magic provided to us by nsIHTMLEditor */
01199             nsres = nsIHTMLEditor_InsertLinkAroundSelection(html_editor, (nsIDOMElement*)anchor_elem);
01200 
01201         nsIHTMLEditor_Release(html_editor);
01202         hres = NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
01203     }
01204 
01205     nsISelection_Release(nsselection);
01206     nsIDOMElement_Release(anchor_elem);
01207 
01208     if (cmdexecopt != OLECMDEXECOPT_DONTPROMPTUSER)
01209         SysFreeString(url);
01210 
01211     TRACE("-- 0x%08x\n", hres);
01212     return hres;
01213 }
01214 
01215 static HRESULT query_selall_status(HTMLDocument *This, OLECMD *cmd)
01216 {
01217     TRACE("(%p)->(%p)\n", This, cmd);
01218 
01219     cmd->cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
01220     return S_OK;
01221 }
01222 
01223 const cmdtable_t editmode_cmds[] = {
01224     {IDM_DELETE,          query_edit_status,    exec_delete},
01225     {IDM_FONTNAME,        query_edit_status,    exec_fontname},
01226     {IDM_FONTSIZE,        query_edit_status,    exec_fontsize},
01227     {IDM_SELECTALL,       query_selall_status , exec_selectall},
01228     {IDM_FORECOLOR,       query_edit_status,    exec_forecolor},
01229     {IDM_BOLD,            query_edit_status,    exec_bold},
01230     {IDM_ITALIC,          query_edit_status,    exec_italic},
01231     {IDM_JUSTIFYCENTER,   query_justify,        exec_justifycenter},
01232     {IDM_JUSTIFYRIGHT,    query_justify,        exec_justifyright},
01233     {IDM_JUSTIFYLEFT,     query_justify,        exec_justifyleft},
01234     {IDM_FONT,            NULL,                 exec_font},
01235     {IDM_UNDERLINE,       query_edit_status,    exec_underline},
01236     {IDM_HORIZONTALLINE,  query_edit_status,    exec_horizontalline},
01237     {IDM_ORDERLIST,       query_edit_status,    exec_orderlist},
01238     {IDM_UNORDERLIST,     query_edit_status,    exec_unorderlist},
01239     {IDM_INDENT,          query_edit_status,    exec_indent},
01240     {IDM_OUTDENT,         query_edit_status,    exec_outdent},
01241     {IDM_COMPOSESETTINGS, NULL,                 exec_composesettings},
01242     {IDM_HYPERLINK,       query_edit_status,    exec_hyperlink},
01243     {IDM_SETDIRTY,        NULL,                 exec_setdirty},
01244     {0,NULL,NULL}
01245 };
01246 
01247 void init_editor(HTMLDocument *This)
01248 {
01249     update_doc(This, UPDATE_UI);
01250 
01251     set_ns_fontname(This, "Times New Roman");
01252 }
01253 
01254 HRESULT editor_is_dirty(HTMLDocument *This)
01255 {
01256     PRBool modified;
01257 
01258     if(!This->doc_obj->nscontainer || !This->doc_obj->nscontainer->editor)
01259         return S_FALSE;
01260 
01261     nsIEditor_GetDocumentModified(This->doc_obj->nscontainer->editor, &modified);
01262 
01263     return modified ? S_OK : S_FALSE;
01264 }

Generated on Sat May 26 2012 04:23:25 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.