editor/composer/src/nsComposerDocumentCommands.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsAutoPtr.h"                  // for nsRefPtr, getter_AddRefs, etc
     8 #include "nsCOMPtr.h"                   // for nsCOMPtr, do_QueryInterface, etc
     9 #include "nsCRT.h"                      // for nsCRT
    10 #include "nsComposerCommands.h"         // for nsSetDocumentOptionsCommand, etc
    11 #include "nsDebug.h"                    // for NS_ENSURE_ARG_POINTER, etc
    12 #include "nsError.h"                    // for NS_ERROR_INVALID_ARG, etc
    13 #include "nsICommandParams.h"           // for nsICommandParams
    14 #include "nsIDOMDocument.h"             // for nsIDOMDocument
    15 #include "nsIDocShell.h"                // for nsIDocShell
    16 #include "nsIDocument.h"                // for nsIDocument
    17 #include "nsIEditingSession.h"          // for nsIEditingSession, etc
    18 #include "nsIEditor.h"                  // for nsIEditor
    19 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor
    20 #include "nsIHTMLInlineTableEditor.h"   // for nsIHTMLInlineTableEditor
    21 #include "nsIHTMLObjectResizer.h"       // for nsIHTMLObjectResizer
    22 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
    23 #include "nsIPresShell.h"               // for nsIPresShell
    24 #include "nsISelectionController.h"     // for nsISelectionController
    25 #include "nsISupportsImpl.h"            // for nsPresContext::Release
    26 #include "nsISupportsUtils.h"           // for NS_IF_ADDREF
    27 #include "nsIURI.h"                     // for nsIURI
    28 #include "nsPresContext.h"              // for nsPresContext
    29 #include "nscore.h"                     // for NS_IMETHODIMP, nsresult, etc
    31 class nsISupports;
    33 //defines
    34 #define STATE_ENABLED  "state_enabled"
    35 #define STATE_ALL "state_all"
    36 #define STATE_ATTRIBUTE "state_attribute"
    37 #define STATE_DATA "state_data"
    39 static
    40 nsresult
    41 GetPresContextFromEditor(nsIEditor *aEditor, nsPresContext **aResult)
    42 {
    43   NS_ENSURE_ARG_POINTER(aResult);
    44   *aResult = nullptr;
    45   NS_ENSURE_ARG_POINTER(aEditor);
    47   nsCOMPtr<nsISelectionController> selCon;
    48   nsresult rv = aEditor->GetSelectionController(getter_AddRefs(selCon));
    49   NS_ENSURE_SUCCESS(rv, rv);
    50   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
    52   nsCOMPtr<nsIPresShell> presShell = do_QueryInterface(selCon);
    53   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
    55   NS_IF_ADDREF(*aResult = presShell->GetPresContext());
    56   return NS_OK;
    57 }
    59 NS_IMETHODIMP
    60 nsSetDocumentOptionsCommand::IsCommandEnabled(const char * aCommandName,
    61                                               nsISupports *refCon,
    62                                               bool *outCmdEnabled)
    63 {
    64   NS_ENSURE_ARG_POINTER(outCmdEnabled);
    65   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
    66   if (editor)
    67     return editor->GetIsSelectionEditable(outCmdEnabled);
    69   *outCmdEnabled = false;
    70   return NS_OK;
    71 }
    73 NS_IMETHODIMP
    74 nsSetDocumentOptionsCommand::DoCommand(const char *aCommandName,
    75                                        nsISupports *refCon)
    76 {
    77   return NS_ERROR_NOT_IMPLEMENTED;
    78 }
    80 NS_IMETHODIMP
    81 nsSetDocumentOptionsCommand::DoCommandParams(const char *aCommandName,
    82                                              nsICommandParams *aParams,
    83                                              nsISupports *refCon)
    84 {
    85   NS_ENSURE_ARG_POINTER(aParams);
    87   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
    88   NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
    90   nsRefPtr<nsPresContext> presContext;
    91   nsresult rv = GetPresContextFromEditor(editor, getter_AddRefs(presContext));
    92   NS_ENSURE_SUCCESS(rv, rv);
    93   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
    95   int32_t animationMode; 
    96   rv = aParams->GetLongValue("imageAnimation", &animationMode);
    97   if (NS_SUCCEEDED(rv))
    98   {
    99     // for possible values of animation mode, see:
   100     // http://lxr.mozilla.org/seamonkey/source/image/public/imgIContainer.idl
   101     presContext->SetImageAnimationMode(animationMode);
   102   }
   104   bool allowPlugins; 
   105   rv = aParams->GetBooleanValue("plugins", &allowPlugins);
   106   if (NS_SUCCEEDED(rv))
   107   {
   108     nsCOMPtr<nsIDocShell> docShell(presContext->GetDocShell());
   109     NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
   111     rv = docShell->SetAllowPlugins(allowPlugins);
   112     NS_ENSURE_SUCCESS(rv, rv);
   113   }
   115   return NS_OK;
   116 }
   118 NS_IMETHODIMP
   119 nsSetDocumentOptionsCommand::GetCommandStateParams(const char *aCommandName,
   120                                                    nsICommandParams *aParams,
   121                                                    nsISupports *refCon)
   122 {
   123   NS_ENSURE_ARG_POINTER(aParams);
   124   NS_ENSURE_ARG_POINTER(refCon);
   126   // The base editor owns most state info
   127   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   128   NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
   130   // Always get the enabled state
   131   bool outCmdEnabled = false;
   132   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
   133   nsresult rv = aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
   134   NS_ENSURE_SUCCESS(rv, rv);
   136   // get pres context
   137   nsRefPtr<nsPresContext> presContext;
   138   rv = GetPresContextFromEditor(editor, getter_AddRefs(presContext));
   139   NS_ENSURE_SUCCESS(rv, rv);
   140   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
   142   int32_t animationMode;
   143   rv = aParams->GetLongValue("imageAnimation", &animationMode);
   144   if (NS_SUCCEEDED(rv))
   145   {
   146     // for possible values of animation mode, see
   147     // http://lxr.mozilla.org/seamonkey/source/image/public/imgIContainer.idl
   148     rv = aParams->SetLongValue("imageAnimation",
   149                                presContext->ImageAnimationMode());
   150     NS_ENSURE_SUCCESS(rv, rv);
   151   }
   153   bool allowPlugins = false; 
   154   rv = aParams->GetBooleanValue("plugins", &allowPlugins);
   155   if (NS_SUCCEEDED(rv))
   156   {
   157     nsCOMPtr<nsIDocShell> docShell(presContext->GetDocShell());
   158     NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
   160     allowPlugins = docShell->PluginsAllowedInCurrentDoc();
   162     rv = aParams->SetBooleanValue("plugins", allowPlugins);
   163     NS_ENSURE_SUCCESS(rv, rv);
   164   }
   166   return NS_OK;
   167 }
   170 /**
   171  *  Commands for document state that may be changed via doCommandParams
   172  *  As of 11/11/02, this is just "cmd_setDocumentModified"
   173  *  Note that you can use the same command class, nsSetDocumentStateCommand,
   174  *    for more than one of this type of command
   175  *    We check the input command param for different behavior
   176  */
   178 NS_IMETHODIMP
   179 nsSetDocumentStateCommand::IsCommandEnabled(const char * aCommandName,
   180                                             nsISupports *refCon,
   181                                             bool *outCmdEnabled)
   182 {
   183   // These commands are always enabled
   184   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   185   *outCmdEnabled = true;
   186   return NS_OK;
   187 }
   189 NS_IMETHODIMP
   190 nsSetDocumentStateCommand::DoCommand(const char *aCommandName,
   191                                      nsISupports *refCon)
   192 {
   193   return NS_ERROR_NOT_IMPLEMENTED;
   194 }
   196 NS_IMETHODIMP
   197 nsSetDocumentStateCommand::DoCommandParams(const char *aCommandName,
   198                                            nsICommandParams *aParams,
   199                                            nsISupports *refCon)
   200 {
   201   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   202   NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
   204   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentModified"))
   205   {
   206     NS_ENSURE_ARG_POINTER(aParams);
   208     bool modified; 
   209     nsresult rv = aParams->GetBooleanValue(STATE_ATTRIBUTE, &modified);
   211     // Should we fail if this param wasn't set?
   212     // I'm not sure we should be that strict
   213     NS_ENSURE_SUCCESS(rv, rv);
   215     if (modified)
   216       return editor->IncrementModificationCount(1);
   218     return editor->ResetModificationCount();
   219   }
   221   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentReadOnly"))
   222   {
   223     NS_ENSURE_ARG_POINTER(aParams);
   224     bool isReadOnly; 
   225     nsresult rvRO = aParams->GetBooleanValue(STATE_ATTRIBUTE, &isReadOnly);
   226     NS_ENSURE_SUCCESS(rvRO, rvRO);
   228     uint32_t flags;
   229     editor->GetFlags(&flags);
   230     if (isReadOnly)
   231       flags |= nsIPlaintextEditor::eEditorReadonlyMask;
   232     else
   233       flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask);
   235     return editor->SetFlags(flags);
   236   }
   238   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS"))
   239   {
   240     NS_ENSURE_ARG_POINTER(aParams);
   241     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
   242     NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
   244     bool desireCSS;
   245     nsresult rvCSS = aParams->GetBooleanValue(STATE_ATTRIBUTE, &desireCSS);
   246     NS_ENSURE_SUCCESS(rvCSS, rvCSS);
   248     return htmleditor->SetIsCSSEnabled(desireCSS);
   249   }
   251   if (!nsCRT::strcmp(aCommandName, "cmd_insertBrOnReturn"))
   252   {
   253     NS_ENSURE_ARG_POINTER(aParams);
   254     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
   255     NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
   257     bool insertBrOnReturn;
   258     nsresult rvBR = aParams->GetBooleanValue(STATE_ATTRIBUTE,
   259                                               &insertBrOnReturn);
   260     NS_ENSURE_SUCCESS(rvBR, rvBR);
   262     return htmleditor->SetReturnInParagraphCreatesNewParagraph(!insertBrOnReturn);
   263   }
   265   if (!nsCRT::strcmp(aCommandName, "cmd_enableObjectResizing"))
   266   {
   267     NS_ENSURE_ARG_POINTER(aParams);
   268     nsCOMPtr<nsIHTMLObjectResizer> resizer = do_QueryInterface(refCon);
   269     NS_ENSURE_TRUE(resizer, NS_ERROR_INVALID_ARG);
   271     bool enabled;
   272     nsresult rvOR = aParams->GetBooleanValue(STATE_ATTRIBUTE, &enabled);
   273     NS_ENSURE_SUCCESS(rvOR, rvOR);
   275     return resizer->SetObjectResizingEnabled(enabled);
   276   }
   278   if (!nsCRT::strcmp(aCommandName, "cmd_enableInlineTableEditing"))
   279   {
   280     NS_ENSURE_ARG_POINTER(aParams);
   281     nsCOMPtr<nsIHTMLInlineTableEditor> editor = do_QueryInterface(refCon);
   282     NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
   284     bool enabled;
   285     nsresult rvOR = aParams->GetBooleanValue(STATE_ATTRIBUTE, &enabled);
   286     NS_ENSURE_SUCCESS(rvOR, rvOR);
   288     return editor->SetInlineTableEditingEnabled(enabled);
   289   }
   291   return NS_ERROR_NOT_IMPLEMENTED;
   292 }
   294 NS_IMETHODIMP
   295 nsSetDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
   296                                                  nsICommandParams *aParams,
   297                                                  nsISupports *refCon)
   298 {
   299   NS_ENSURE_ARG_POINTER(aParams);
   300   NS_ENSURE_ARG_POINTER(refCon);
   302   // The base editor owns most state info
   303   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   304   NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
   306   // Always get the enabled state
   307   bool outCmdEnabled = false;
   308   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
   309   nsresult rv = aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
   310   NS_ENSURE_SUCCESS(rv, rv);
   312   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentModified"))
   313   {
   314     bool modified;
   315     rv = editor->GetDocumentModified(&modified);
   316     NS_ENSURE_SUCCESS(rv, rv);
   318     return aParams->SetBooleanValue(STATE_ATTRIBUTE, modified);
   319   }
   321   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentReadOnly"))
   322   {
   323     NS_ENSURE_ARG_POINTER(aParams);
   325     uint32_t flags;
   326     editor->GetFlags(&flags);
   327     bool isReadOnly = flags & nsIPlaintextEditor::eEditorReadonlyMask;
   328     return aParams->SetBooleanValue(STATE_ATTRIBUTE, isReadOnly);
   329   }
   331   if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS"))
   332   {
   333     NS_ENSURE_ARG_POINTER(aParams);
   334     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
   335     NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
   337     bool isCSS;
   338     htmleditor->GetIsCSSEnabled(&isCSS);
   339     return aParams->SetBooleanValue(STATE_ALL, isCSS);
   340   }
   342   if (!nsCRT::strcmp(aCommandName, "cmd_insertBrOnReturn"))
   343   {
   344     NS_ENSURE_ARG_POINTER(aParams);
   345     nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
   346     NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
   348     bool createPOnReturn;
   349     htmleditor->GetReturnInParagraphCreatesNewParagraph(&createPOnReturn);
   350     return aParams->SetBooleanValue(STATE_ATTRIBUTE, !createPOnReturn);
   351   }
   353   if (!nsCRT::strcmp(aCommandName, "cmd_enableObjectResizing"))
   354   {
   355     NS_ENSURE_ARG_POINTER(aParams);
   356     nsCOMPtr<nsIHTMLObjectResizer> resizer = do_QueryInterface(refCon);
   357     NS_ENSURE_TRUE(resizer, NS_ERROR_INVALID_ARG);
   359     bool enabled;
   360     resizer->GetObjectResizingEnabled(&enabled);
   361     return aParams->SetBooleanValue(STATE_ATTRIBUTE, enabled);
   362   }
   364   if (!nsCRT::strcmp(aCommandName, "cmd_enableInlineTableEditing"))
   365   {
   366     NS_ENSURE_ARG_POINTER(aParams);
   367     nsCOMPtr<nsIHTMLInlineTableEditor> editor = do_QueryInterface(refCon);
   368     NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
   370     bool enabled;
   371     editor->GetInlineTableEditingEnabled(&enabled);
   372     return aParams->SetBooleanValue(STATE_ATTRIBUTE, enabled);
   373   }
   375   return NS_ERROR_NOT_IMPLEMENTED;
   376 }
   378 /**
   379  * Commands just for state notification 
   380  *  As of 11/21/02, possible commands are:
   381  *    "obs_documentCreated"
   382  *    "obs_documentWillBeDestroyed"
   383  *    "obs_documentLocationChanged"
   384  *  Note that you can use the same command class, nsDocumentStateCommand
   385  *    for these or future observer commands.
   386  *    We check the input command param for different behavior
   387  *
   388  *  How to use:
   389  *  1. Get the nsICommandManager for the current editor
   390  *  2. Implement an nsIObserve object, e.g:
   391  *
   392  *    void Observe( 
   393  *        in nsISupports aSubject, // The nsICommandManager calling this Observer
   394  *        in string      aTopic,   // command name, e.g.:"obs_documentCreated"
   395  *                                 //    or "obs_documentWillBeDestroyed"
   396           in wstring     aData );  // ignored (set to "command_status_changed")
   397  *
   398  *  3. Add the observer by:
   399  *       commandManager.addObserver(observeobject, obs_documentCreated);
   400  *  4. In the appropriate location in editorSession, editor, or commands code, 
   401  *     trigger the notification of this observer by something like:
   402  *
   403  *  nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(mDocShell);
   404  *  nsCOMPtr<nsPICommandUpdater> commandUpdater = do_QueryInterface(commandManager);
   405  *  NS_ENSURE_TRUE(commandUpdater, NS_ERROR_FAILURE);
   406  *    commandUpdater->CommandStatusChanged(obs_documentCreated);
   407  *
   408  *  5. Use GetCommandStateParams() to obtain state information
   409  *     e.g., any creation state codes when creating an editor are 
   410  *     supplied for "obs_documentCreated" command in the 
   411  *     "state_data" param's value
   412  *
   413  */
   415 NS_IMETHODIMP
   416 nsDocumentStateCommand::IsCommandEnabled(const char* aCommandName,
   417                                          nsISupports *refCon,
   418                                          bool *outCmdEnabled)
   419 {
   420   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   421   // Always return false to discourage callers from using DoCommand()
   422   *outCmdEnabled = false;
   423   return NS_OK;
   424 }
   426 NS_IMETHODIMP
   427 nsDocumentStateCommand::DoCommand(const char *aCommandName,
   428                                   nsISupports *refCon)
   429 {
   430   return NS_ERROR_NOT_IMPLEMENTED;
   431 }
   433 NS_IMETHODIMP
   434 nsDocumentStateCommand::DoCommandParams(const char *aCommandName,
   435                                         nsICommandParams *aParams,
   436                                         nsISupports *refCon)
   437 {
   438   return NS_ERROR_NOT_IMPLEMENTED;
   439 }
   441 NS_IMETHODIMP
   442 nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
   443                                               nsICommandParams *aParams,
   444                                               nsISupports *refCon)
   445 {
   446   NS_ENSURE_ARG_POINTER(aParams);
   447   NS_ENSURE_ARG_POINTER(aCommandName);
   448   nsresult rv;
   450   if (!nsCRT::strcmp(aCommandName, "obs_documentCreated"))
   451   {
   452     uint32_t editorStatus = nsIEditingSession::eEditorErrorUnknown;
   454     nsCOMPtr<nsIEditingSession> editingSession = do_QueryInterface(refCon);
   455     if (editingSession)
   456     {
   457       // refCon is initially set to nsIEditingSession until editor
   458       //  is successfully created and source doc is loaded
   459       // Embedder gets error status if this fails
   460       // If called before startup is finished, 
   461       //    status = eEditorCreationInProgress
   462       rv = editingSession->GetEditorStatus(&editorStatus);
   463       NS_ENSURE_SUCCESS(rv, rv);
   464     }
   465     else
   466     {
   467       // If refCon is an editor, then everything started up OK!
   468       nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   469       if (editor)
   470         editorStatus = nsIEditingSession::eEditorOK;
   471     }
   473     // Note that if refCon is not-null, but is neither
   474     // an nsIEditingSession or nsIEditor, we return "eEditorErrorUnknown"
   475     aParams->SetLongValue(STATE_DATA, editorStatus);
   476     return NS_OK;
   477   }  
   478   else if (!nsCRT::strcmp(aCommandName, "obs_documentLocationChanged"))
   479   {
   480     nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   481     if (editor)
   482     {
   483       nsCOMPtr<nsIDOMDocument> domDoc;
   484       editor->GetDocument(getter_AddRefs(domDoc));
   485       nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
   486       NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
   488       nsIURI *uri = doc->GetDocumentURI();
   489       NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
   491       return aParams->SetISupportsValue(STATE_DATA, (nsISupports*)uri);
   492     }
   493     return NS_OK;
   494   }  
   496   return NS_ERROR_NOT_IMPLEMENTED;
   497 }

mercurial