Back to index

lightning-sunbird  0.9+nobinonly
nsComposerDocumentCommands.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Ryan Cassin <rcassin@supernova.org>
00024  *   Daniel Glazman <glazman@netscape.com>
00025  *   Charles Manske <cmanske@netscape.com>
00026  *   Kathleen Brade <brade@netscape.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 
00043 #include "nsIEditor.h"
00044 #include "nsIEditingSession.h"
00045 #include "nsIPlaintextEditor.h"
00046 #include "nsIHTMLEditor.h"
00047 #include "nsIHTMLObjectResizer.h"
00048 #include "nsIHTMLInlineTableEditor.h"
00049 
00050 #include "nsIDOMDocument.h"
00051 #include "nsIDocument.h"
00052 #include "nsISelectionController.h"
00053 #include "nsIPresShell.h"
00054 #include "nsPresContext.h"
00055 #include "nsIDocShell.h"
00056 #include "nsIURI.h"
00057 
00058 #include "nsCOMPtr.h"
00059 
00060 #include "nsComposerCommands.h"
00061 #include "nsICommandParams.h"
00062 #include "nsCRT.h"
00063 
00064 //defines
00065 #define STATE_ENABLED  "state_enabled"
00066 #define STATE_ATTRIBUTE "state_attribute"
00067 #define STATE_DATA "state_data"
00068 
00069 static
00070 nsresult
00071 GetPresContextFromEditor(nsIEditor *aEditor, nsPresContext **aResult)
00072 {
00073   NS_ENSURE_ARG_POINTER(aResult);
00074   *aResult = nsnull;
00075   NS_ENSURE_ARG_POINTER(aEditor);
00076 
00077   nsCOMPtr<nsISelectionController> selCon;
00078   nsresult rv = aEditor->GetSelectionController(getter_AddRefs(selCon));
00079   if (NS_FAILED(rv)) return rv;
00080   if (!selCon) return NS_ERROR_FAILURE;
00081 
00082   nsCOMPtr<nsIPresShell> presShell = do_QueryInterface(selCon);
00083   if (!presShell) return NS_ERROR_FAILURE;
00084 
00085   NS_IF_ADDREF(*aResult = presShell->GetPresContext());
00086   return NS_OK;
00087 }
00088 
00089 NS_IMETHODIMP
00090 nsSetDocumentOptionsCommand::IsCommandEnabled(const char * aCommandName,
00091                                               nsISupports *refCon,
00092                                               PRBool *outCmdEnabled)
00093 {
00094   NS_ENSURE_ARG_POINTER(outCmdEnabled);
00095   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
00096   *outCmdEnabled = (editor != nsnull);
00097   return NS_OK;
00098 }
00099 
00100 NS_IMETHODIMP
00101 nsSetDocumentOptionsCommand::DoCommand(const char *aCommandName,
00102                                        nsISupports *refCon)
00103 {
00104   return NS_ERROR_NOT_IMPLEMENTED;
00105 }
00106 
00107 NS_IMETHODIMP
00108 nsSetDocumentOptionsCommand::DoCommandParams(const char *aCommandName,
00109                                              nsICommandParams *aParams,
00110                                              nsISupports *refCon)
00111 {
00112   NS_ENSURE_ARG_POINTER(aParams);
00113 
00114   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00115   if (!editor) return NS_ERROR_INVALID_ARG;
00116 
00117   nsCOMPtr<nsPresContext> presContext;
00118   nsresult rv = GetPresContextFromEditor(editor, getter_AddRefs(presContext));
00119   if (NS_FAILED(rv)) return rv;
00120   if (!presContext) return NS_ERROR_FAILURE;
00121 
00122   PRInt32 animationMode; 
00123   rv = aParams->GetLongValue("imageAnimation", &animationMode);
00124   if (NS_SUCCEEDED(rv))
00125   {
00126     // for possible values of animation mode, see:
00127     // http://lxr.mozilla.org/seamonkey/source/modules/libpr0n/public/imgIContainer.idl
00128     presContext->SetImageAnimationMode(animationMode);
00129   }
00130 
00131   PRBool allowPlugins; 
00132   rv = aParams->GetBooleanValue("plugins", &allowPlugins);
00133   if (NS_SUCCEEDED(rv))
00134   {
00135     nsCOMPtr<nsISupports> container = presContext->GetContainer();
00136     if (!container) return NS_ERROR_FAILURE;
00137 
00138     nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container, &rv));
00139     if (NS_FAILED(rv)) return rv;
00140     if (!docShell) return NS_ERROR_FAILURE;
00141 
00142     rv = docShell->SetAllowPlugins(allowPlugins);
00143     if (NS_FAILED(rv)) return rv;
00144   }
00145 
00146   return NS_OK;
00147 }
00148 
00149 NS_IMETHODIMP
00150 nsSetDocumentOptionsCommand::GetCommandStateParams(const char *aCommandName,
00151                                                    nsICommandParams *aParams,
00152                                                    nsISupports *refCon)
00153 {
00154   NS_ENSURE_ARG_POINTER(aParams);
00155   NS_ENSURE_ARG_POINTER(refCon);
00156 
00157   // The base editor owns most state info
00158   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00159   if (!editor) return NS_ERROR_INVALID_ARG;
00160 
00161   // Always get the enabled state
00162   PRBool outCmdEnabled = PR_FALSE;
00163   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
00164   nsresult rv = aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
00165   NS_ENSURE_SUCCESS(rv, rv);
00166 
00167   // get pres context
00168   nsCOMPtr<nsPresContext> presContext;
00169   rv = GetPresContextFromEditor(editor, getter_AddRefs(presContext));
00170   if (NS_FAILED(rv)) return rv;
00171   if (!presContext) return NS_ERROR_FAILURE;
00172 
00173   PRInt32 animationMode;
00174   rv = aParams->GetLongValue("imageAnimation", &animationMode);
00175   if (NS_SUCCEEDED(rv))
00176   {
00177     // for possible values of animation mode, see
00178     // http://lxr.mozilla.org/seamonkey/source/modules/libpr0n/public/imgIContainer.idl
00179     rv = aParams->SetLongValue("imageAnimation",
00180                                presContext->ImageAnimationMode());
00181     if (NS_FAILED(rv)) return rv;
00182   }
00183 
00184   PRBool allowPlugins; 
00185   rv = aParams->GetBooleanValue("plugins", &allowPlugins);
00186   if (NS_SUCCEEDED(rv))
00187   {
00188     nsCOMPtr<nsISupports> container = presContext->GetContainer();
00189     if (!container) return NS_ERROR_FAILURE;
00190 
00191     nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container, &rv));
00192     if (NS_FAILED(rv)) return rv;
00193     if (!docShell) return NS_ERROR_FAILURE;
00194 
00195     rv = docShell->GetAllowPlugins(&allowPlugins);
00196     if (NS_FAILED(rv)) return rv;
00197 
00198     rv = aParams->SetBooleanValue("plugins", allowPlugins);
00199     if (NS_FAILED(rv)) return rv;
00200   }
00201 
00202   return NS_OK;
00203 }
00204 
00205 
00214 NS_IMETHODIMP
00215 nsSetDocumentStateCommand::IsCommandEnabled(const char * aCommandName,
00216                                             nsISupports *refCon,
00217                                             PRBool *outCmdEnabled)
00218 {
00219   NS_ENSURE_ARG_POINTER(outCmdEnabled);
00220   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00221   *outCmdEnabled = (editor != nsnull);
00222   return NS_OK;
00223 }
00224 
00225 NS_IMETHODIMP
00226 nsSetDocumentStateCommand::DoCommand(const char *aCommandName,
00227                                      nsISupports *refCon)
00228 {
00229   return NS_ERROR_NOT_IMPLEMENTED;
00230 }
00231 
00232 NS_IMETHODIMP
00233 nsSetDocumentStateCommand::DoCommandParams(const char *aCommandName,
00234                                            nsICommandParams *aParams,
00235                                            nsISupports *refCon)
00236 {
00237   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00238   if (!editor) 
00239     return NS_ERROR_INVALID_ARG;
00240 
00241   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentModified"))
00242   {
00243     NS_ENSURE_ARG_POINTER(aParams);
00244 
00245     PRBool modified; 
00246     nsresult rv = aParams->GetBooleanValue(STATE_ATTRIBUTE, &modified);
00247 
00248     // Should we fail if this param wasn't set?
00249     // I'm not sure we should be that strict
00250     if (NS_FAILED(rv))
00251       return rv;
00252 
00253     if (modified)
00254       return editor->IncrementModificationCount(1);
00255 
00256     return editor->ResetModificationCount();
00257   }
00258 
00259   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentReadOnly"))
00260   {
00261     NS_ENSURE_ARG_POINTER(aParams);
00262     PRBool isReadOnly; 
00263     nsresult rvRO = aParams->GetBooleanValue(STATE_ATTRIBUTE, &isReadOnly);
00264     if (NS_FAILED(rvRO))
00265       return rvRO;
00266 
00267     PRUint32 flags;
00268     editor->GetFlags(&flags);
00269     if (isReadOnly)
00270       flags |= nsIPlaintextEditor::eEditorReadonlyMask;
00271     else
00272       flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask);
00273 
00274     return editor->SetFlags(flags);
00275   }
00276 
00277   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS"))
00278   {
00279     NS_ENSURE_ARG_POINTER(aParams);
00280     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
00281     if (!htmleditor) 
00282       return NS_ERROR_INVALID_ARG;
00283 
00284     PRBool desireCSS;
00285     nsresult rvCSS = aParams->GetBooleanValue(STATE_ATTRIBUTE, &desireCSS);
00286     if (NS_FAILED(rvCSS))
00287       return rvCSS;
00288 
00289     return htmleditor->SetIsCSSEnabled(desireCSS);
00290   }
00291 
00292   if (!nsCRT::strcmp(aCommandName, "cmd_insertBrOnReturn"))
00293   {
00294     NS_ENSURE_ARG_POINTER(aParams);
00295     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
00296     if (!htmleditor) 
00297       return NS_ERROR_INVALID_ARG;
00298 
00299     PRBool insertBrOnReturn;
00300     nsresult rvBR = aParams->GetBooleanValue(STATE_ATTRIBUTE,
00301                                               &insertBrOnReturn);
00302     if (NS_FAILED(rvBR))
00303       return rvBR;
00304 
00305     return htmleditor->SetReturnInParagraphCreatesNewParagraph(!insertBrOnReturn);
00306   }
00307 
00308   if (!nsCRT::strcmp(aCommandName, "cmd_enableObjectResizing"))
00309   {
00310     NS_ENSURE_ARG_POINTER(aParams);
00311     nsCOMPtr<nsIHTMLObjectResizer> resizer = do_QueryInterface(refCon);
00312     if (!resizer)
00313       return NS_ERROR_INVALID_ARG;
00314 
00315     PRBool enabled;
00316     nsresult rvOR = aParams->GetBooleanValue(STATE_ATTRIBUTE, &enabled);
00317     if (NS_FAILED(rvOR))
00318       return rvOR;
00319 
00320     return resizer->SetObjectResizingEnabled(enabled);
00321   }
00322 
00323   if (!nsCRT::strcmp(aCommandName, "cmd_enableInlineTableEditing"))
00324   {
00325     NS_ENSURE_ARG_POINTER(aParams);
00326     nsCOMPtr<nsIHTMLInlineTableEditor> editor = do_QueryInterface(refCon);
00327     if (!editor)
00328       return NS_ERROR_INVALID_ARG;
00329 
00330     PRBool enabled;
00331     nsresult rvOR = aParams->GetBooleanValue(STATE_ATTRIBUTE, &enabled);
00332     if (NS_FAILED(rvOR))
00333       return rvOR;
00334 
00335     return editor->SetInlineTableEditingEnabled(enabled);
00336   }
00337 
00338   return NS_ERROR_NOT_IMPLEMENTED;
00339 }
00340 
00341 NS_IMETHODIMP
00342 nsSetDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
00343                                                  nsICommandParams *aParams,
00344                                                  nsISupports *refCon)
00345 {
00346   NS_ENSURE_ARG_POINTER(aParams);
00347   NS_ENSURE_ARG_POINTER(refCon);
00348 
00349   // The base editor owns most state info
00350   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00351   if (!editor) 
00352     return NS_ERROR_INVALID_ARG;
00353 
00354   // Always get the enabled state
00355   PRBool outCmdEnabled = PR_FALSE;
00356   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
00357   nsresult rv = aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
00358   NS_ENSURE_SUCCESS(rv, rv);
00359 
00360   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentModified"))
00361   {
00362     PRBool modified;
00363     rv = editor->GetDocumentModified(&modified);
00364     NS_ENSURE_SUCCESS(rv, rv);
00365 
00366     return aParams->SetBooleanValue(STATE_ATTRIBUTE, modified);
00367   }
00368 
00369   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentReadOnly"))
00370   {
00371     NS_ENSURE_ARG_POINTER(aParams);
00372 
00373     PRUint32 flags;
00374     editor->GetFlags(&flags);
00375     PRBool isReadOnly = flags & nsIPlaintextEditor::eEditorReadonlyMask;
00376     return aParams->SetBooleanValue(STATE_ATTRIBUTE, isReadOnly);
00377   }
00378 
00379   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS"))
00380   {
00381     NS_ENSURE_ARG_POINTER(aParams);
00382     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
00383     if (!htmleditor)
00384       return NS_ERROR_INVALID_ARG;
00385 
00386     PRBool isCSS;
00387     htmleditor->GetIsCSSEnabled(&isCSS);
00388     return aParams->SetBooleanValue(STATE_ATTRIBUTE, isCSS);
00389   }
00390 
00391   if (!nsCRT::strcmp(aCommandName, "cmd_insertBrOnReturn"))
00392   {
00393     NS_ENSURE_ARG_POINTER(aParams);
00394     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
00395     if (!htmleditor)
00396       return NS_ERROR_INVALID_ARG;
00397 
00398     PRBool createPOnReturn;
00399     htmleditor->GetReturnInParagraphCreatesNewParagraph(&createPOnReturn);
00400     return aParams->SetBooleanValue(STATE_ATTRIBUTE, !createPOnReturn);
00401   }
00402 
00403   if (!nsCRT::strcmp(aCommandName, "cmd_enableObjectResizing"))
00404   {
00405     NS_ENSURE_ARG_POINTER(aParams);
00406     nsCOMPtr<nsIHTMLObjectResizer> resizer = do_QueryInterface(refCon);
00407     if (!resizer)
00408       return NS_ERROR_INVALID_ARG;
00409 
00410     PRBool enabled;
00411     resizer->GetObjectResizingEnabled(&enabled);
00412     return aParams->SetBooleanValue(STATE_ATTRIBUTE, enabled);
00413   }
00414 
00415   if (!nsCRT::strcmp(aCommandName, "cmd_enableInlineTableEditing"))
00416   {
00417     NS_ENSURE_ARG_POINTER(aParams);
00418     nsCOMPtr<nsIHTMLInlineTableEditor> editor = do_QueryInterface(refCon);
00419     if (!editor)
00420       return NS_ERROR_INVALID_ARG;
00421 
00422     PRBool enabled;
00423     editor->GetInlineTableEditingEnabled(&enabled);
00424     return aParams->SetBooleanValue(STATE_ATTRIBUTE, enabled);
00425   }
00426 
00427   return NS_ERROR_NOT_IMPLEMENTED;
00428 }
00429 
00467 #ifdef XP_MAC
00468 #pragma mark -
00469 #endif
00470 
00471 NS_IMETHODIMP
00472 nsDocumentStateCommand::IsCommandEnabled(const char* aCommandName,
00473                                          nsISupports *refCon,
00474                                          PRBool *outCmdEnabled)
00475 {
00476   NS_ENSURE_ARG_POINTER(outCmdEnabled);
00477   // Always return false to discourage callers from using DoCommand()
00478   *outCmdEnabled = PR_FALSE;
00479   return NS_OK;
00480 }
00481 
00482 NS_IMETHODIMP
00483 nsDocumentStateCommand::DoCommand(const char *aCommandName,
00484                                   nsISupports *refCon)
00485 {
00486   return NS_ERROR_NOT_IMPLEMENTED;
00487 }
00488 
00489 NS_IMETHODIMP
00490 nsDocumentStateCommand::DoCommandParams(const char *aCommandName,
00491                                         nsICommandParams *aParams,
00492                                         nsISupports *refCon)
00493 {
00494   return NS_ERROR_NOT_IMPLEMENTED;
00495 }
00496 
00497 NS_IMETHODIMP
00498 nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
00499                                               nsICommandParams *aParams,
00500                                               nsISupports *refCon)
00501 {
00502   NS_ENSURE_ARG_POINTER(aParams);
00503   NS_ENSURE_ARG_POINTER(aCommandName);
00504   nsresult rv;
00505 
00506   if (!nsCRT::strcmp(aCommandName, "obs_documentCreated"))
00507   {
00508     PRUint32 editorStatus = nsIEditingSession::eEditorErrorUnknown;
00509 
00510     nsCOMPtr<nsIEditingSession> editingSession = do_QueryInterface(refCon);
00511     if (editingSession)
00512     {
00513       // refCon is initially set to nsIEditingSession until editor
00514       //  is successfully created and source doc is loaded
00515       // Embedder gets error status if this fails
00516       // If called before startup is finished, 
00517       //    status = eEditorCreationInProgress
00518       rv = editingSession->GetEditorStatus(&editorStatus);
00519       NS_ENSURE_SUCCESS(rv, rv);
00520     }
00521     else
00522     {
00523       // If refCon is an editor, then everything started up OK!
00524       nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00525       if (editor)
00526         editorStatus = nsIEditingSession::eEditorOK;
00527     }
00528 
00529     // Note that if refCon is not-null, but is neither
00530     // an nsIEditingSession or nsIEditor, we return "eEditorErrorUnknown"
00531     aParams->SetLongValue(STATE_DATA, editorStatus);
00532     return NS_OK;
00533   }  
00534   else if (!nsCRT::strcmp(aCommandName, "obs_documentLocationChanged"))
00535   {
00536     nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
00537     if (editor)
00538     {
00539       nsCOMPtr<nsIDOMDocument> domDoc;
00540       editor->GetDocument(getter_AddRefs(domDoc));
00541       nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
00542       if (!doc) return NS_ERROR_FAILURE;
00543 
00544       nsIURI *uri = doc->GetDocumentURI();
00545       if (!uri) return NS_ERROR_FAILURE;
00546 
00547       return aParams->SetISupportsValue(STATE_DATA, (nsISupports*)uri);
00548     }
00549     return NS_OK;
00550   }  
00551 
00552   return NS_ERROR_NOT_IMPLEMENTED;
00553 }