1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Ryan Cassin <rcassin@supernova.org>
24 * Daniel Glazman <glazman@netscape.com>
25 * Charles Manske <cmanske@netscape.com>
26 * Kathleen Brade <brade@netscape.com>
28 * Alternatively, the contents of this file may be used under the terms of
29 * either of the GNU General Public License Version 2 or later (the "GPL"),
30 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
43 #include "nsIEditor.h"
44 #include "nsIEditingSession.h"
45 #include "nsIPlaintextEditor.h"
46 #include "nsIHTMLEditor.h"
47 #include "nsIHTMLObjectResizer.h"
48 #include "nsIHTMLInlineTableEditor.h"
50 #include "nsIDOMDocument.h"
51 #include "nsIDocument.h"
52 #include "nsISelectionController.h"
53 #include "nsIPresShell.h"
54 #include "nsPresContext.h"
55 #include "nsIDocShell.h"
60 #include "nsComposerCommands.h"
61 #include "nsICommandParams.h"
65 #define STATE_ENABLED "state_enabled"
66 #define STATE_ATTRIBUTE "state_attribute"
67 #define STATE_DATA "state_data"
71 GetPresContextFromEditor(nsIEditor
*aEditor
, nsPresContext
**aResult
)
73 NS_ENSURE_ARG_POINTER(aResult
);
75 NS_ENSURE_ARG_POINTER(aEditor
);
77 nsCOMPtr
<nsISelectionController
> selCon
;
78 nsresult rv
= aEditor
->GetSelectionController(getter_AddRefs(selCon
));
79 if (NS_FAILED(rv
)) return rv
;
80 if (!selCon
) return NS_ERROR_FAILURE
;
82 nsCOMPtr
<nsIPresShell
> presShell
= do_QueryInterface(selCon
);
83 if (!presShell
) return NS_ERROR_FAILURE
;
85 NS_IF_ADDREF(*aResult
= presShell
->GetPresContext());
90 nsSetDocumentOptionsCommand::IsCommandEnabled(const char * aCommandName
,
92 PRBool
*outCmdEnabled
)
94 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
95 nsCOMPtr
<nsIHTMLEditor
> editor
= do_QueryInterface(refCon
);
96 *outCmdEnabled
= (editor
!= nsnull
);
101 nsSetDocumentOptionsCommand::DoCommand(const char *aCommandName
,
104 return NS_ERROR_NOT_IMPLEMENTED
;
108 nsSetDocumentOptionsCommand::DoCommandParams(const char *aCommandName
,
109 nsICommandParams
*aParams
,
112 NS_ENSURE_ARG_POINTER(aParams
);
114 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
115 if (!editor
) return NS_ERROR_INVALID_ARG
;
117 nsCOMPtr
<nsPresContext
> presContext
;
118 nsresult rv
= GetPresContextFromEditor(editor
, getter_AddRefs(presContext
));
119 if (NS_FAILED(rv
)) return rv
;
120 if (!presContext
) return NS_ERROR_FAILURE
;
122 PRInt32 animationMode
;
123 rv
= aParams
->GetLongValue("imageAnimation", &animationMode
);
124 if (NS_SUCCEEDED(rv
))
126 // for possible values of animation mode, see:
127 // http://lxr.mozilla.org/seamonkey/source/modules/libpr0n/public/imgIContainer.idl
128 presContext
->SetImageAnimationMode(animationMode
);
132 rv
= aParams
->GetBooleanValue("plugins", &allowPlugins
);
133 if (NS_SUCCEEDED(rv
))
135 nsCOMPtr
<nsISupports
> container
= presContext
->GetContainer();
136 if (!container
) return NS_ERROR_FAILURE
;
138 nsCOMPtr
<nsIDocShell
> docShell(do_QueryInterface(container
, &rv
));
139 if (NS_FAILED(rv
)) return rv
;
140 if (!docShell
) return NS_ERROR_FAILURE
;
142 rv
= docShell
->SetAllowPlugins(allowPlugins
);
143 if (NS_FAILED(rv
)) return rv
;
150 nsSetDocumentOptionsCommand::GetCommandStateParams(const char *aCommandName
,
151 nsICommandParams
*aParams
,
154 NS_ENSURE_ARG_POINTER(aParams
);
155 NS_ENSURE_ARG_POINTER(refCon
);
157 // The base editor owns most state info
158 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
159 if (!editor
) return NS_ERROR_INVALID_ARG
;
161 // Always get the enabled state
162 PRBool outCmdEnabled
= PR_FALSE
;
163 IsCommandEnabled(aCommandName
, refCon
, &outCmdEnabled
);
164 nsresult rv
= aParams
->SetBooleanValue(STATE_ENABLED
, outCmdEnabled
);
165 NS_ENSURE_SUCCESS(rv
, rv
);
168 nsCOMPtr
<nsPresContext
> presContext
;
169 rv
= GetPresContextFromEditor(editor
, getter_AddRefs(presContext
));
170 if (NS_FAILED(rv
)) return rv
;
171 if (!presContext
) return NS_ERROR_FAILURE
;
173 PRInt32 animationMode
;
174 rv
= aParams
->GetLongValue("imageAnimation", &animationMode
);
175 if (NS_SUCCEEDED(rv
))
177 // for possible values of animation mode, see
178 // http://lxr.mozilla.org/seamonkey/source/modules/libpr0n/public/imgIContainer.idl
179 rv
= aParams
->SetLongValue("imageAnimation",
180 presContext
->ImageAnimationMode());
181 if (NS_FAILED(rv
)) return rv
;
185 rv
= aParams
->GetBooleanValue("plugins", &allowPlugins
);
186 if (NS_SUCCEEDED(rv
))
188 nsCOMPtr
<nsISupports
> container
= presContext
->GetContainer();
189 if (!container
) return NS_ERROR_FAILURE
;
191 nsCOMPtr
<nsIDocShell
> docShell(do_QueryInterface(container
, &rv
));
192 if (NS_FAILED(rv
)) return rv
;
193 if (!docShell
) return NS_ERROR_FAILURE
;
195 rv
= docShell
->GetAllowPlugins(&allowPlugins
);
196 if (NS_FAILED(rv
)) return rv
;
198 rv
= aParams
->SetBooleanValue("plugins", allowPlugins
);
199 if (NS_FAILED(rv
)) return rv
;
207 * Commands for document state that may be changed via doCommandParams
208 * As of 11/11/02, this is just "cmd_setDocumentModified"
209 * Note that you can use the same command class, nsSetDocumentStateCommand,
210 * for more than one of this type of command
211 * We check the input command param for different behavior
215 nsSetDocumentStateCommand::IsCommandEnabled(const char * aCommandName
,
217 PRBool
*outCmdEnabled
)
219 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
220 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
221 *outCmdEnabled
= (editor
!= nsnull
);
226 nsSetDocumentStateCommand::DoCommand(const char *aCommandName
,
229 return NS_ERROR_NOT_IMPLEMENTED
;
233 nsSetDocumentStateCommand::DoCommandParams(const char *aCommandName
,
234 nsICommandParams
*aParams
,
237 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
239 return NS_ERROR_INVALID_ARG
;
241 if (!nsCRT::strcmp(aCommandName
, "cmd_setDocumentModified"))
243 NS_ENSURE_ARG_POINTER(aParams
);
246 nsresult rv
= aParams
->GetBooleanValue(STATE_ATTRIBUTE
, &modified
);
248 // Should we fail if this param wasn't set?
249 // I'm not sure we should be that strict
254 return editor
->IncrementModificationCount(1);
256 return editor
->ResetModificationCount();
259 if (!nsCRT::strcmp(aCommandName
, "cmd_setDocumentReadOnly"))
261 NS_ENSURE_ARG_POINTER(aParams
);
263 nsresult rvRO
= aParams
->GetBooleanValue(STATE_ATTRIBUTE
, &isReadOnly
);
268 editor
->GetFlags(&flags
);
270 flags
|= nsIPlaintextEditor::eEditorReadonlyMask
;
272 flags
&= ~(nsIPlaintextEditor::eEditorReadonlyMask
);
274 return editor
->SetFlags(flags
);
277 if (!nsCRT::strcmp(aCommandName
, "cmd_setDocumentUseCSS"))
279 NS_ENSURE_ARG_POINTER(aParams
);
280 nsCOMPtr
<nsIHTMLEditor
> htmleditor
= do_QueryInterface(refCon
);
282 return NS_ERROR_INVALID_ARG
;
285 nsresult rvCSS
= aParams
->GetBooleanValue(STATE_ATTRIBUTE
, &desireCSS
);
286 if (NS_FAILED(rvCSS
))
289 return htmleditor
->SetIsCSSEnabled(desireCSS
);
292 if (!nsCRT::strcmp(aCommandName
, "cmd_insertBrOnReturn"))
294 NS_ENSURE_ARG_POINTER(aParams
);
295 nsCOMPtr
<nsIHTMLEditor
> htmleditor
= do_QueryInterface(refCon
);
297 return NS_ERROR_INVALID_ARG
;
299 PRBool insertBrOnReturn
;
300 nsresult rvBR
= aParams
->GetBooleanValue(STATE_ATTRIBUTE
,
305 return htmleditor
->SetReturnInParagraphCreatesNewParagraph(!insertBrOnReturn
);
308 if (!nsCRT::strcmp(aCommandName
, "cmd_enableObjectResizing"))
310 NS_ENSURE_ARG_POINTER(aParams
);
311 nsCOMPtr
<nsIHTMLObjectResizer
> resizer
= do_QueryInterface(refCon
);
313 return NS_ERROR_INVALID_ARG
;
316 nsresult rvOR
= aParams
->GetBooleanValue(STATE_ATTRIBUTE
, &enabled
);
320 return resizer
->SetObjectResizingEnabled(enabled
);
323 if (!nsCRT::strcmp(aCommandName
, "cmd_enableInlineTableEditing"))
325 NS_ENSURE_ARG_POINTER(aParams
);
326 nsCOMPtr
<nsIHTMLInlineTableEditor
> editor
= do_QueryInterface(refCon
);
328 return NS_ERROR_INVALID_ARG
;
331 nsresult rvOR
= aParams
->GetBooleanValue(STATE_ATTRIBUTE
, &enabled
);
335 return editor
->SetInlineTableEditingEnabled(enabled
);
338 return NS_ERROR_NOT_IMPLEMENTED
;
342 nsSetDocumentStateCommand::GetCommandStateParams(const char *aCommandName
,
343 nsICommandParams
*aParams
,
346 NS_ENSURE_ARG_POINTER(aParams
);
347 NS_ENSURE_ARG_POINTER(refCon
);
349 // The base editor owns most state info
350 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
352 return NS_ERROR_INVALID_ARG
;
354 // Always get the enabled state
355 PRBool outCmdEnabled
= PR_FALSE
;
356 IsCommandEnabled(aCommandName
, refCon
, &outCmdEnabled
);
357 nsresult rv
= aParams
->SetBooleanValue(STATE_ENABLED
, outCmdEnabled
);
358 NS_ENSURE_SUCCESS(rv
, rv
);
360 if (!nsCRT::strcmp(aCommandName
, "cmd_setDocumentModified"))
363 rv
= editor
->GetDocumentModified(&modified
);
364 NS_ENSURE_SUCCESS(rv
, rv
);
366 return aParams
->SetBooleanValue(STATE_ATTRIBUTE
, modified
);
369 if (!nsCRT::strcmp(aCommandName
, "cmd_setDocumentReadOnly"))
371 NS_ENSURE_ARG_POINTER(aParams
);
374 editor
->GetFlags(&flags
);
375 PRBool isReadOnly
= flags
& nsIPlaintextEditor::eEditorReadonlyMask
;
376 return aParams
->SetBooleanValue(STATE_ATTRIBUTE
, isReadOnly
);
379 if (!nsCRT::strcmp(aCommandName
, "cmd_setDocumentUseCSS"))
381 NS_ENSURE_ARG_POINTER(aParams
);
382 nsCOMPtr
<nsIHTMLEditor
> htmleditor
= do_QueryInterface(refCon
);
384 return NS_ERROR_INVALID_ARG
;
387 htmleditor
->GetIsCSSEnabled(&isCSS
);
388 return aParams
->SetBooleanValue(STATE_ATTRIBUTE
, isCSS
);
391 if (!nsCRT::strcmp(aCommandName
, "cmd_insertBrOnReturn"))
393 NS_ENSURE_ARG_POINTER(aParams
);
394 nsCOMPtr
<nsIHTMLEditor
> htmleditor
= do_QueryInterface(refCon
);
396 return NS_ERROR_INVALID_ARG
;
398 PRBool createPOnReturn
;
399 htmleditor
->GetReturnInParagraphCreatesNewParagraph(&createPOnReturn
);
400 return aParams
->SetBooleanValue(STATE_ATTRIBUTE
, !createPOnReturn
);
403 if (!nsCRT::strcmp(aCommandName
, "cmd_enableObjectResizing"))
405 NS_ENSURE_ARG_POINTER(aParams
);
406 nsCOMPtr
<nsIHTMLObjectResizer
> resizer
= do_QueryInterface(refCon
);
408 return NS_ERROR_INVALID_ARG
;
411 resizer
->GetObjectResizingEnabled(&enabled
);
412 return aParams
->SetBooleanValue(STATE_ATTRIBUTE
, enabled
);
415 if (!nsCRT::strcmp(aCommandName
, "cmd_enableInlineTableEditing"))
417 NS_ENSURE_ARG_POINTER(aParams
);
418 nsCOMPtr
<nsIHTMLInlineTableEditor
> editor
= do_QueryInterface(refCon
);
420 return NS_ERROR_INVALID_ARG
;
423 editor
->GetInlineTableEditingEnabled(&enabled
);
424 return aParams
->SetBooleanValue(STATE_ATTRIBUTE
, enabled
);
427 return NS_ERROR_NOT_IMPLEMENTED
;
431 * Commands just for state notification
432 * As of 11/21/02, possible commands are:
433 * "obs_documentCreated"
434 * "obs_documentWillBeDestroyed"
435 * "obs_documentLocationChanged"
436 * Note that you can use the same command class, nsDocumentStateCommand
437 * for these or future observer commands.
438 * We check the input command param for different behavior
441 * 1. Get the nsICommandManager for the current editor
442 * 2. Implement an nsIObserve object, e.g:
445 * in nsISupports aSubject, // The nsICommandManager calling this Observer
446 * in string aTopic, // command name, e.g.:"obs_documentCreated"
447 * // or "obs_documentWillBeDestroyed"
448 in wstring aData ); // ignored (set to "command_status_changed")
450 * 3. Add the observer by:
451 * commandManager.addObserver(observeobject, obs_documentCreated);
452 * 4. In the appropriate location in editorSession, editor, or commands code,
453 * trigger the notification of this observer by something like:
455 * nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(mDocShell);
456 * nsCOMPtr<nsPICommandUpdater> commandUpdater = do_QueryInterface(commandManager);
457 * if (!commandUpdater) return NS_ERROR_FAILURE;
458 * commandUpdater->CommandStatusChanged(obs_documentCreated);
460 * 5. Use GetCommandStateParams() to obtain state information
461 * e.g., any creation state codes when creating an editor are
462 * supplied for "obs_documentCreated" command in the
463 * "state_data" param's value
472 nsDocumentStateCommand::IsCommandEnabled(const char* aCommandName
,
474 PRBool
*outCmdEnabled
)
476 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
477 // Always return false to discourage callers from using DoCommand()
478 *outCmdEnabled
= PR_FALSE
;
483 nsDocumentStateCommand::DoCommand(const char *aCommandName
,
486 return NS_ERROR_NOT_IMPLEMENTED
;
490 nsDocumentStateCommand::DoCommandParams(const char *aCommandName
,
491 nsICommandParams
*aParams
,
494 return NS_ERROR_NOT_IMPLEMENTED
;
498 nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName
,
499 nsICommandParams
*aParams
,
502 NS_ENSURE_ARG_POINTER(aParams
);
503 NS_ENSURE_ARG_POINTER(aCommandName
);
506 if (!nsCRT::strcmp(aCommandName
, "obs_documentCreated"))
508 PRUint32 editorStatus
= nsIEditingSession::eEditorErrorUnknown
;
510 nsCOMPtr
<nsIEditingSession
> editingSession
= do_QueryInterface(refCon
);
513 // refCon is initially set to nsIEditingSession until editor
514 // is successfully created and source doc is loaded
515 // Embedder gets error status if this fails
516 // If called before startup is finished,
517 // status = eEditorCreationInProgress
518 rv
= editingSession
->GetEditorStatus(&editorStatus
);
519 NS_ENSURE_SUCCESS(rv
, rv
);
523 // If refCon is an editor, then everything started up OK!
524 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
526 editorStatus
= nsIEditingSession::eEditorOK
;
529 // Note that if refCon is not-null, but is neither
530 // an nsIEditingSession or nsIEditor, we return "eEditorErrorUnknown"
531 aParams
->SetLongValue(STATE_DATA
, editorStatus
);
534 else if (!nsCRT::strcmp(aCommandName
, "obs_documentLocationChanged"))
536 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
539 nsCOMPtr
<nsIDOMDocument
> domDoc
;
540 editor
->GetDocument(getter_AddRefs(domDoc
));
541 nsCOMPtr
<nsIDocument
> doc
= do_QueryInterface(domDoc
);
542 if (!doc
) return NS_ERROR_FAILURE
;
544 nsIURI
*uri
= doc
->GetDocumentURI();
545 if (!uri
) return NS_ERROR_FAILURE
;
547 return aParams
->SetISupportsValue(STATE_DATA
, (nsISupports
*)uri
);
552 return NS_ERROR_NOT_IMPLEMENTED
;