summaryrefslogtreecommitdiffstats
path: root/editor/composer/nsComposerDocumentCommands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/composer/nsComposerDocumentCommands.cpp')
-rw-r--r--editor/composer/nsComposerDocumentCommands.cpp480
1 files changed, 480 insertions, 0 deletions
diff --git a/editor/composer/nsComposerDocumentCommands.cpp b/editor/composer/nsComposerDocumentCommands.cpp
new file mode 100644
index 000000000..d44e940f6
--- /dev/null
+++ b/editor/composer/nsComposerDocumentCommands.cpp
@@ -0,0 +1,480 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#include "nsCOMPtr.h" // for nsCOMPtr, do_QueryInterface, etc
+#include "nsCRT.h" // for nsCRT
+#include "nsComposerCommands.h" // for nsSetDocumentOptionsCommand, etc
+#include "nsDebug.h" // for NS_ENSURE_ARG_POINTER, etc
+#include "nsError.h" // for NS_ERROR_INVALID_ARG, etc
+#include "nsICommandParams.h" // for nsICommandParams
+#include "nsIDOMDocument.h" // for nsIDOMDocument
+#include "nsIDocShell.h" // for nsIDocShell
+#include "nsIDocument.h" // for nsIDocument
+#include "nsIEditingSession.h" // for nsIEditingSession, etc
+#include "nsIEditor.h" // for nsIEditor
+#include "nsIHTMLEditor.h" // for nsIHTMLEditor
+#include "nsIHTMLInlineTableEditor.h" // for nsIHTMLInlineTableEditor
+#include "nsIHTMLObjectResizer.h" // for nsIHTMLObjectResizer
+#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
+#include "nsIPresShell.h" // for nsIPresShell
+#include "nsISelectionController.h" // for nsISelectionController
+#include "nsISupportsImpl.h" // for nsPresContext::Release
+#include "nsISupportsUtils.h" // for NS_IF_ADDREF
+#include "nsIURI.h" // for nsIURI
+#include "nsPresContext.h" // for nsPresContext
+#include "nscore.h" // for NS_IMETHODIMP, nsresult, etc
+
+class nsISupports;
+
+//defines
+#define STATE_ENABLED "state_enabled"
+#define STATE_ALL "state_all"
+#define STATE_ATTRIBUTE "state_attribute"
+#define STATE_DATA "state_data"
+
+static
+nsresult
+GetPresContextFromEditor(nsIEditor *aEditor, nsPresContext **aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ *aResult = nullptr;
+ NS_ENSURE_ARG_POINTER(aEditor);
+
+ nsCOMPtr<nsISelectionController> selCon;
+ nsresult rv = aEditor->GetSelectionController(getter_AddRefs(selCon));
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIPresShell> presShell = do_QueryInterface(selCon);
+ NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+
+ NS_IF_ADDREF(*aResult = presShell->GetPresContext());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSetDocumentOptionsCommand::IsCommandEnabled(const char * aCommandName,
+ nsISupports *refCon,
+ bool *outCmdEnabled)
+{
+ NS_ENSURE_ARG_POINTER(outCmdEnabled);
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ if (editor) {
+ return editor->GetIsSelectionEditable(outCmdEnabled);
+ }
+
+ *outCmdEnabled = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSetDocumentOptionsCommand::DoCommand(const char *aCommandName,
+ nsISupports *refCon)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSetDocumentOptionsCommand::DoCommandParams(const char *aCommandName,
+ nsICommandParams *aParams,
+ nsISupports *refCon)
+{
+ NS_ENSURE_ARG_POINTER(aParams);
+
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
+
+ RefPtr<nsPresContext> presContext;
+ nsresult rv = GetPresContextFromEditor(editor, getter_AddRefs(presContext));
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
+
+ int32_t animationMode;
+ rv = aParams->GetLongValue("imageAnimation", &animationMode);
+ if (NS_SUCCEEDED(rv)) {
+ // for possible values of animation mode, see:
+ // http://lxr.mozilla.org/seamonkey/source/image/public/imgIContainer.idl
+ presContext->SetImageAnimationMode(animationMode);
+ }
+
+ bool allowPlugins;
+ rv = aParams->GetBooleanValue("plugins", &allowPlugins);
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr<nsIDocShell> docShell(presContext->GetDocShell());
+ NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+ rv = docShell->SetAllowPlugins(allowPlugins);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSetDocumentOptionsCommand::GetCommandStateParams(const char *aCommandName,
+ nsICommandParams *aParams,
+ nsISupports *refCon)
+{
+ NS_ENSURE_ARG_POINTER(aParams);
+ NS_ENSURE_ARG_POINTER(refCon);
+
+ // The base editor owns most state info
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
+
+ // Always get the enabled state
+ bool outCmdEnabled = false;
+ IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
+ nsresult rv = aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // get pres context
+ RefPtr<nsPresContext> presContext;
+ rv = GetPresContextFromEditor(editor, getter_AddRefs(presContext));
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
+
+ int32_t animationMode;
+ rv = aParams->GetLongValue("imageAnimation", &animationMode);
+ if (NS_SUCCEEDED(rv)) {
+ // for possible values of animation mode, see
+ // http://lxr.mozilla.org/seamonkey/source/image/public/imgIContainer.idl
+ rv = aParams->SetLongValue("imageAnimation",
+ presContext->ImageAnimationMode());
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ bool allowPlugins = false;
+ rv = aParams->GetBooleanValue("plugins", &allowPlugins);
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr<nsIDocShell> docShell(presContext->GetDocShell());
+ NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+ allowPlugins = docShell->PluginsAllowedInCurrentDoc();
+
+ rv = aParams->SetBooleanValue("plugins", allowPlugins);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+
+/**
+ * Commands for document state that may be changed via doCommandParams
+ * As of 11/11/02, this is just "cmd_setDocumentModified"
+ * Note that you can use the same command class, nsSetDocumentStateCommand,
+ * for more than one of this type of command
+ * We check the input command param for different behavior
+ */
+
+NS_IMETHODIMP
+nsSetDocumentStateCommand::IsCommandEnabled(const char * aCommandName,
+ nsISupports *refCon,
+ bool *outCmdEnabled)
+{
+ // These commands are always enabled
+ NS_ENSURE_ARG_POINTER(outCmdEnabled);
+ *outCmdEnabled = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSetDocumentStateCommand::DoCommand(const char *aCommandName,
+ nsISupports *refCon)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSetDocumentStateCommand::DoCommandParams(const char *aCommandName,
+ nsICommandParams *aParams,
+ nsISupports *refCon)
+{
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentModified")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+
+ bool modified;
+ nsresult rv = aParams->GetBooleanValue(STATE_ATTRIBUTE, &modified);
+
+ // Should we fail if this param wasn't set?
+ // I'm not sure we should be that strict
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (modified) {
+ return editor->IncrementModificationCount(1);
+ }
+
+ return editor->ResetModificationCount();
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentReadOnly")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ bool isReadOnly;
+ nsresult rvRO = aParams->GetBooleanValue(STATE_ATTRIBUTE, &isReadOnly);
+ NS_ENSURE_SUCCESS(rvRO, rvRO);
+
+ uint32_t flags;
+ editor->GetFlags(&flags);
+ if (isReadOnly) {
+ flags |= nsIPlaintextEditor::eEditorReadonlyMask;
+ } else {
+ flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask);
+ }
+
+ return editor->SetFlags(flags);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
+
+ bool desireCSS;
+ nsresult rvCSS = aParams->GetBooleanValue(STATE_ATTRIBUTE, &desireCSS);
+ NS_ENSURE_SUCCESS(rvCSS, rvCSS);
+
+ return htmleditor->SetIsCSSEnabled(desireCSS);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_insertBrOnReturn")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
+
+ bool insertBrOnReturn;
+ nsresult rvBR = aParams->GetBooleanValue(STATE_ATTRIBUTE,
+ &insertBrOnReturn);
+ NS_ENSURE_SUCCESS(rvBR, rvBR);
+
+ return htmleditor->SetReturnInParagraphCreatesNewParagraph(!insertBrOnReturn);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_enableObjectResizing")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLObjectResizer> resizer = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(resizer, NS_ERROR_INVALID_ARG);
+
+ bool enabled;
+ nsresult rvOR = aParams->GetBooleanValue(STATE_ATTRIBUTE, &enabled);
+ NS_ENSURE_SUCCESS(rvOR, rvOR);
+
+ return resizer->SetObjectResizingEnabled(enabled);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_enableInlineTableEditing")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLInlineTableEditor> editor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
+
+ bool enabled;
+ nsresult rvOR = aParams->GetBooleanValue(STATE_ATTRIBUTE, &enabled);
+ NS_ENSURE_SUCCESS(rvOR, rvOR);
+
+ return editor->SetInlineTableEditingEnabled(enabled);
+ }
+
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSetDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
+ nsICommandParams *aParams,
+ nsISupports *refCon)
+{
+ NS_ENSURE_ARG_POINTER(aParams);
+ NS_ENSURE_ARG_POINTER(refCon);
+
+ // The base editor owns most state info
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
+
+ // Always get the enabled state
+ bool outCmdEnabled = false;
+ IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
+ nsresult rv = aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentModified")) {
+ bool modified;
+ rv = editor->GetDocumentModified(&modified);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return aParams->SetBooleanValue(STATE_ATTRIBUTE, modified);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentReadOnly")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+
+ uint32_t flags;
+ editor->GetFlags(&flags);
+ bool isReadOnly = flags & nsIPlaintextEditor::eEditorReadonlyMask;
+ return aParams->SetBooleanValue(STATE_ATTRIBUTE, isReadOnly);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
+
+ bool isCSS;
+ htmleditor->GetIsCSSEnabled(&isCSS);
+ return aParams->SetBooleanValue(STATE_ALL, isCSS);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_insertBrOnReturn")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLEditor> htmleditor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(htmleditor, NS_ERROR_INVALID_ARG);
+
+ bool createPOnReturn;
+ htmleditor->GetReturnInParagraphCreatesNewParagraph(&createPOnReturn);
+ return aParams->SetBooleanValue(STATE_ATTRIBUTE, !createPOnReturn);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_enableObjectResizing")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLObjectResizer> resizer = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(resizer, NS_ERROR_INVALID_ARG);
+
+ bool enabled;
+ resizer->GetObjectResizingEnabled(&enabled);
+ return aParams->SetBooleanValue(STATE_ATTRIBUTE, enabled);
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "cmd_enableInlineTableEditing")) {
+ NS_ENSURE_ARG_POINTER(aParams);
+ nsCOMPtr<nsIHTMLInlineTableEditor> editor = do_QueryInterface(refCon);
+ NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
+
+ bool enabled;
+ editor->GetInlineTableEditingEnabled(&enabled);
+ return aParams->SetBooleanValue(STATE_ATTRIBUTE, enabled);
+ }
+
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * Commands just for state notification
+ * As of 11/21/02, possible commands are:
+ * "obs_documentCreated"
+ * "obs_documentWillBeDestroyed"
+ * "obs_documentLocationChanged"
+ * Note that you can use the same command class, nsDocumentStateCommand
+ * for these or future observer commands.
+ * We check the input command param for different behavior
+ *
+ * How to use:
+ * 1. Get the nsICommandManager for the current editor
+ * 2. Implement an nsIObserve object, e.g:
+ *
+ * void Observe(
+ * in nsISupports aSubject, // The nsICommandManager calling this Observer
+ * in string aTopic, // command name, e.g.:"obs_documentCreated"
+ * // or "obs_documentWillBeDestroyed"
+ in wstring aData ); // ignored (set to "command_status_changed")
+ *
+ * 3. Add the observer by:
+ * commandManager.addObserver(observeobject, obs_documentCreated);
+ * 4. In the appropriate location in editorSession, editor, or commands code,
+ * trigger the notification of this observer by something like:
+ *
+ * nsCOMPtr<nsICommandManager> commandManager = mDocShell->GetCommandManager();
+ * nsCOMPtr<nsPICommandUpdater> commandUpdater = do_QueryInterface(commandManager);
+ * NS_ENSURE_TRUE(commandUpdater, NS_ERROR_FAILURE);
+ * commandUpdater->CommandStatusChanged(obs_documentCreated);
+ *
+ * 5. Use GetCommandStateParams() to obtain state information
+ * e.g., any creation state codes when creating an editor are
+ * supplied for "obs_documentCreated" command in the
+ * "state_data" param's value
+ *
+ */
+
+NS_IMETHODIMP
+nsDocumentStateCommand::IsCommandEnabled(const char* aCommandName,
+ nsISupports *refCon,
+ bool *outCmdEnabled)
+{
+ NS_ENSURE_ARG_POINTER(outCmdEnabled);
+ // Always return false to discourage callers from using DoCommand()
+ *outCmdEnabled = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocumentStateCommand::DoCommand(const char *aCommandName,
+ nsISupports *refCon)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocumentStateCommand::DoCommandParams(const char *aCommandName,
+ nsICommandParams *aParams,
+ nsISupports *refCon)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
+ nsICommandParams *aParams,
+ nsISupports *refCon)
+{
+ NS_ENSURE_ARG_POINTER(aParams);
+ NS_ENSURE_ARG_POINTER(aCommandName);
+ nsresult rv;
+
+ if (!nsCRT::strcmp(aCommandName, "obs_documentCreated")) {
+ uint32_t editorStatus = nsIEditingSession::eEditorErrorUnknown;
+
+ nsCOMPtr<nsIEditingSession> editingSession = do_QueryInterface(refCon);
+ if (editingSession) {
+ // refCon is initially set to nsIEditingSession until editor
+ // is successfully created and source doc is loaded
+ // Embedder gets error status if this fails
+ // If called before startup is finished,
+ // status = eEditorCreationInProgress
+ rv = editingSession->GetEditorStatus(&editorStatus);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ // If refCon is an editor, then everything started up OK!
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ if (editor) {
+ editorStatus = nsIEditingSession::eEditorOK;
+ }
+ }
+
+ // Note that if refCon is not-null, but is neither
+ // an nsIEditingSession or nsIEditor, we return "eEditorErrorUnknown"
+ aParams->SetLongValue(STATE_DATA, editorStatus);
+ return NS_OK;
+ }
+
+ if (!nsCRT::strcmp(aCommandName, "obs_documentLocationChanged")) {
+ nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
+ if (!editor) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ editor->GetDocument(getter_AddRefs(domDoc));
+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+ NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
+
+ nsIURI *uri = doc->GetDocumentURI();
+ NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
+
+ return aParams->SetISupportsValue(STATE_DATA, (nsISupports*)uri);
+ }
+
+ return NS_ERROR_NOT_IMPLEMENTED;
+}