From cd9c83ab3cef8eb5d2c36dff457986a941f3a0a3 Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Wed, 16 Feb 2000 01:38:02 +0000 Subject: [PATCH] Register the interface state maintainer as a transaction listener, for bug 18395. r=pinkerton git-svn-id: svn://10.0.0.236/trunk@61006 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/editor/base/nsEditorShell.cpp | 29 ++- mozilla/editor/base/nsInterfaceState.cpp | 167 +++++++++++++----- mozilla/editor/base/nsInterfaceState.h | 29 ++- mozilla/editor/composer/src/nsEditorShell.cpp | 29 ++- .../editor/composer/src/nsInterfaceState.cpp | 167 +++++++++++++----- .../editor/composer/src/nsInterfaceState.h | 29 ++- 6 files changed, 348 insertions(+), 102 deletions(-) diff --git a/mozilla/editor/base/nsEditorShell.cpp b/mozilla/editor/base/nsEditorShell.cpp index d175119281f..961b1c0002f 100644 --- a/mozilla/editor/base/nsEditorShell.cpp +++ b/mozilla/editor/base/nsEditorShell.cpp @@ -80,7 +80,7 @@ #include "nsEditorController.h" #include "nsIControllers.h" #include "nsIDocShell.h" - +#include "nsITransactionManager.h" /////////////////////////////////////// // Editor Includes @@ -124,8 +124,6 @@ static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID); static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); static NS_DEFINE_CID(kCommonDialogsCID, NS_CommonDialog_CID ); static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID); -static NS_DEFINE_CID(kEditorControllerCID, NS_EDITORCONTROLLER_CID); -static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); /* Define Interface IDs */ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -352,23 +350,38 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl) // and set it up as a doc state listener nsCOMPtr editor = do_QueryInterface(mEditor, &rv); if (NS_FAILED(rv)) return rv; - rv = editor->AddDocumentStateListener(mStateMaintainer); + rv = editor->AddDocumentStateListener(NS_STATIC_CAST(nsIDocumentStateListener*, mStateMaintainer)); if (NS_FAILED(rv)) return rv; + // and as a transaction listener + nsCOMPtr txnMgr; + editor->GetTransactionManager(getter_AddRefs(txnMgr)); + if (txnMgr) + { + txnMgr->AddListener(NS_STATIC_CAST(nsITransactionListener*, mStateMaintainer)); + } + + if (NS_SUCCEEDED(rv) && mContentWindow) { nsCOMPtr controller; nsCOMPtr controllers; - rv = nsComponentManager::CreateInstance(kEditorControllerCID, nsnull, NS_GET_IID(nsIController), getter_AddRefs(controller)); + rv = nsComponentManager::CreateInstance("component://netscape/editor/editorcontroller", + nsnull, + NS_GET_IID(nsIController), + getter_AddRefs(controller)); if (NS_SUCCEEDED(rv) && controller) { rv = mContentWindow->GetControllers(getter_AddRefs(controllers)); if (NS_SUCCEEDED(rv) && controllers) { - nsCOMPtr ieditcontroller = do_QueryInterface(controller); - ieditcontroller->SetEditor(editor);//weak link + nsCOMPtr editorController = do_QueryInterface(controller); + rv = editorController->Init(); + if (NS_FAILED(rv)) return rv; + + editorController->SetEditor(editor);//weak link - rv = controllers->InsertControllerAt(0,controller); + rv = controllers->InsertControllerAt(0, controller); } } } diff --git a/mozilla/editor/base/nsInterfaceState.cpp b/mozilla/editor/base/nsInterfaceState.cpp index 6059612b9ef..bdaafb803ac 100644 --- a/mozilla/editor/base/nsInterfaceState.cpp +++ b/mozilla/editor/base/nsInterfaceState.cpp @@ -36,9 +36,12 @@ #include "nsIDOMSelection.h" #include "nsIDOMAttr.h" #include "nsIDOMXULCommandDispatcher.h" +#include "nsIScriptGlobalObject.h" +#include "nsIDOMWindow.h" #include "nsIEditor.h" #include "nsIHTMLEditor.h" +#include "nsITransactionManager.h" #include "nsInterfaceState.h" @@ -47,11 +50,13 @@ nsInterfaceState::nsInterfaceState() : mEditor(nsnull) , mChromeDoc(nsnull) +, mDOMWindow(nsnull) , mBoldState(eStateUninitialized) , mItalicState(eStateUninitialized) , mUnderlineState(eStateUninitialized) , mDirtyState(eStateUninitialized) , mSelectionCollapsed(eStateUninitialized) +, mFirstDoOfFirstUndo(PR_TRUE) { NS_INIT_REFCNT(); } @@ -62,38 +67,7 @@ nsInterfaceState::~nsInterfaceState() NS_IMPL_ADDREF(nsInterfaceState); NS_IMPL_RELEASE(nsInterfaceState); - -NS_IMETHODIMP -nsInterfaceState::QueryInterface(const nsIID& aIID, void** aInstancePtr) -{ - if (nsnull == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - *aInstancePtr = nsnull; - if (aIID.Equals(NS_GET_IID(nsIDOMSelectionListener))) - { - *aInstancePtr = (void*)(nsIDOMSelectionListener*)this; - AddRef(); - return NS_OK; - } - - if (aIID.Equals(NS_GET_IID(nsIDocumentStateListener))) - { - *aInstancePtr = (void*)(nsIDocumentStateListener*)this; - AddRef(); - return NS_OK; - } - - if (aIID.Equals(NS_GET_IID(nsISupports))) - { - *aInstancePtr = (void*)(nsISupports *)(nsIDOMSelectionListener*)this; - AddRef(); - return NS_OK; - } - - return NS_NOINTERFACE; -} +NS_IMPL_QUERY_INTERFACE3(nsInterfaceState, nsIDOMSelectionListener, nsIDocumentStateListener, nsITransactionListener); NS_IMETHODIMP nsInterfaceState::Init(nsIHTMLEditor* aEditor, nsIDOMXULDocument *aChromeDoc) @@ -143,23 +117,132 @@ nsInterfaceState::NotifySelectionChanged() PRBool isCollapsed = SelectionIsCollapsed(); if (isCollapsed != mSelectionCollapsed) { + CallUpdateCommands(nsAutoString("select")); mSelectionCollapsed = isCollapsed; - - // force command updating to happen. Slow, we'll speed it up later - // we could do this in JS, but we can't be a selection listener there - nsCOMPtr dispatcher; - nsresult rv = mChromeDoc->GetCommandDispatcher(getter_AddRefs(dispatcher)); - if (NS_FAILED(rv)) return rv; - if (!dispatcher) return NS_ERROR_UNEXPECTED; - - rv = dispatcher->UpdateCommands(nsAutoString("selection-change")); - if (NS_FAILED(rv)) return rv; } return ForceUpdate(); } +NS_IMETHODIMP nsInterfaceState::WillDo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidDo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aDoResult) +{ + // only need to update if the status of the Undo menu item changes. + PRInt32 undoCount; + aManager->GetNumberOfUndoItems(&undoCount); + if (undoCount == 1) + { + if (mFirstDoOfFirstUndo) + CallUpdateCommands(nsAutoString("undo")); + mFirstDoOfFirstUndo = PR_FALSE; + } + + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillUndo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidUndo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aUndoResult) +{ + PRInt32 undoCount; + aManager->GetNumberOfUndoItems(&undoCount); + if (undoCount == 0) + mFirstDoOfFirstUndo = PR_TRUE; // reset the state for the next do + + CallUpdateCommands(nsAutoString("undo")); + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillRedo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidRedo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aRedoResult) +{ + CallUpdateCommands(nsAutoString("undo")); + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidBeginBatch(nsITransactionManager *aManager, nsresult aResult) +{ + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidEndBatch(nsITransactionManager *aManager, nsresult aResult) +{ + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillMerge(nsITransactionManager *aManager, + nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidMerge(nsITransactionManager *aManager, + nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, + PRBool aDidMerge, nsresult aMergeResult) +{ + return NS_OK; +} + + +nsresult nsInterfaceState::CallUpdateCommands(const nsString& aCommand) +{ + if (!mDOMWindow) + { + nsCOMPtr editor = do_QueryInterface(mEditor); + if (!editor) return NS_ERROR_FAILURE; + + nsCOMPtr domDoc; + editor->GetDocument(getter_AddRefs(domDoc)); + if (!domDoc) return NS_ERROR_FAILURE; + + nsCOMPtr theDoc = do_QueryInterface(domDoc); + if (!theDoc) return NS_ERROR_FAILURE; + + nsCOMPtr scriptGlobalObject; + theDoc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); + + nsCOMPtr domWindow = do_QueryInterface(scriptGlobalObject); + if (!domWindow) return NS_ERROR_FAILURE; + mDOMWindow = domWindow; + } + + return mDOMWindow->UpdateCommands(aCommand); +} + NS_IMETHODIMP nsInterfaceState::ForceUpdate() { diff --git a/mozilla/editor/base/nsInterfaceState.h b/mozilla/editor/base/nsInterfaceState.h index dfd27b85055..dde6b6a40f8 100644 --- a/mozilla/editor/base/nsInterfaceState.h +++ b/mozilla/editor/base/nsInterfaceState.h @@ -27,6 +27,7 @@ #include "nsIDOMSelectionListener.h" #include "nsIDocumentStateListener.h" +#include "nsITransactionListener.h" #include "nsIWebShell.h" class nsIHTMLEditor; @@ -36,7 +37,8 @@ class nsIDOMXULDocument; // This is currently somewhat tied to a given XUL UI implementation class nsInterfaceState : public nsIDOMSelectionListener, - public nsIDocumentStateListener + public nsIDocumentStateListener, + public nsITransactionListener { public: @@ -57,6 +59,26 @@ public: NS_DECL_NSIDOCUMENTSTATELISTENER + + /** nsITransactionListener interfaces + */ + + NS_IMETHOD WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt); + NS_IMETHOD DidDo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aDoResult); + NS_IMETHOD WillUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt); + NS_IMETHOD DidUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aUndoResult); + NS_IMETHOD WillRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt); + NS_IMETHOD DidRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aRedoResult); + NS_IMETHOD WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt); + NS_IMETHOD DidBeginBatch(nsITransactionManager *aManager, nsresult aResult); + NS_IMETHOD WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt); + NS_IMETHOD DidEndBatch(nsITransactionManager *aManager, nsresult aResult); + NS_IMETHOD WillMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction, + nsITransaction *aTransactionToMerge, PRBool *aInterrupt); + NS_IMETHOD DidMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction, + nsITransaction *aTransactionToMerge, + PRBool aDidMerge, nsresult aMergeResult); + protected: enum { @@ -76,12 +98,16 @@ protected: nsresult UpdateFontFace(const char* observerName, const char* attributeName, nsString& ioFontString); nsresult UpdateDirtyState(PRBool aNowDirty); + nsresult CallUpdateCommands(const nsString& aCommand); + // this class should not hold references to the editor or editorShell. Doing // so would result in cirular reference chains. nsIHTMLEditor* mEditor; // the HTML editor nsIDOMXULDocument* mChromeDoc; // XUL document for the chrome area + nsIDOMWindow* mDOMWindow; // nsIDOMWindow used for calling UpdateCommands + // current state PRInt8 mBoldState; PRInt8 mItalicState; @@ -91,6 +117,7 @@ protected: PRInt8 mSelectionCollapsed; + PRPackedBool mFirstDoOfFirstUndo; nsString mParagraphFormat; nsString mFontString; diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp index d175119281f..961b1c0002f 100644 --- a/mozilla/editor/composer/src/nsEditorShell.cpp +++ b/mozilla/editor/composer/src/nsEditorShell.cpp @@ -80,7 +80,7 @@ #include "nsEditorController.h" #include "nsIControllers.h" #include "nsIDocShell.h" - +#include "nsITransactionManager.h" /////////////////////////////////////// // Editor Includes @@ -124,8 +124,6 @@ static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID); static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); static NS_DEFINE_CID(kCommonDialogsCID, NS_CommonDialog_CID ); static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID); -static NS_DEFINE_CID(kEditorControllerCID, NS_EDITORCONTROLLER_CID); -static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); /* Define Interface IDs */ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -352,23 +350,38 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl) // and set it up as a doc state listener nsCOMPtr editor = do_QueryInterface(mEditor, &rv); if (NS_FAILED(rv)) return rv; - rv = editor->AddDocumentStateListener(mStateMaintainer); + rv = editor->AddDocumentStateListener(NS_STATIC_CAST(nsIDocumentStateListener*, mStateMaintainer)); if (NS_FAILED(rv)) return rv; + // and as a transaction listener + nsCOMPtr txnMgr; + editor->GetTransactionManager(getter_AddRefs(txnMgr)); + if (txnMgr) + { + txnMgr->AddListener(NS_STATIC_CAST(nsITransactionListener*, mStateMaintainer)); + } + + if (NS_SUCCEEDED(rv) && mContentWindow) { nsCOMPtr controller; nsCOMPtr controllers; - rv = nsComponentManager::CreateInstance(kEditorControllerCID, nsnull, NS_GET_IID(nsIController), getter_AddRefs(controller)); + rv = nsComponentManager::CreateInstance("component://netscape/editor/editorcontroller", + nsnull, + NS_GET_IID(nsIController), + getter_AddRefs(controller)); if (NS_SUCCEEDED(rv) && controller) { rv = mContentWindow->GetControllers(getter_AddRefs(controllers)); if (NS_SUCCEEDED(rv) && controllers) { - nsCOMPtr ieditcontroller = do_QueryInterface(controller); - ieditcontroller->SetEditor(editor);//weak link + nsCOMPtr editorController = do_QueryInterface(controller); + rv = editorController->Init(); + if (NS_FAILED(rv)) return rv; + + editorController->SetEditor(editor);//weak link - rv = controllers->InsertControllerAt(0,controller); + rv = controllers->InsertControllerAt(0, controller); } } } diff --git a/mozilla/editor/composer/src/nsInterfaceState.cpp b/mozilla/editor/composer/src/nsInterfaceState.cpp index 6059612b9ef..bdaafb803ac 100644 --- a/mozilla/editor/composer/src/nsInterfaceState.cpp +++ b/mozilla/editor/composer/src/nsInterfaceState.cpp @@ -36,9 +36,12 @@ #include "nsIDOMSelection.h" #include "nsIDOMAttr.h" #include "nsIDOMXULCommandDispatcher.h" +#include "nsIScriptGlobalObject.h" +#include "nsIDOMWindow.h" #include "nsIEditor.h" #include "nsIHTMLEditor.h" +#include "nsITransactionManager.h" #include "nsInterfaceState.h" @@ -47,11 +50,13 @@ nsInterfaceState::nsInterfaceState() : mEditor(nsnull) , mChromeDoc(nsnull) +, mDOMWindow(nsnull) , mBoldState(eStateUninitialized) , mItalicState(eStateUninitialized) , mUnderlineState(eStateUninitialized) , mDirtyState(eStateUninitialized) , mSelectionCollapsed(eStateUninitialized) +, mFirstDoOfFirstUndo(PR_TRUE) { NS_INIT_REFCNT(); } @@ -62,38 +67,7 @@ nsInterfaceState::~nsInterfaceState() NS_IMPL_ADDREF(nsInterfaceState); NS_IMPL_RELEASE(nsInterfaceState); - -NS_IMETHODIMP -nsInterfaceState::QueryInterface(const nsIID& aIID, void** aInstancePtr) -{ - if (nsnull == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - *aInstancePtr = nsnull; - if (aIID.Equals(NS_GET_IID(nsIDOMSelectionListener))) - { - *aInstancePtr = (void*)(nsIDOMSelectionListener*)this; - AddRef(); - return NS_OK; - } - - if (aIID.Equals(NS_GET_IID(nsIDocumentStateListener))) - { - *aInstancePtr = (void*)(nsIDocumentStateListener*)this; - AddRef(); - return NS_OK; - } - - if (aIID.Equals(NS_GET_IID(nsISupports))) - { - *aInstancePtr = (void*)(nsISupports *)(nsIDOMSelectionListener*)this; - AddRef(); - return NS_OK; - } - - return NS_NOINTERFACE; -} +NS_IMPL_QUERY_INTERFACE3(nsInterfaceState, nsIDOMSelectionListener, nsIDocumentStateListener, nsITransactionListener); NS_IMETHODIMP nsInterfaceState::Init(nsIHTMLEditor* aEditor, nsIDOMXULDocument *aChromeDoc) @@ -143,23 +117,132 @@ nsInterfaceState::NotifySelectionChanged() PRBool isCollapsed = SelectionIsCollapsed(); if (isCollapsed != mSelectionCollapsed) { + CallUpdateCommands(nsAutoString("select")); mSelectionCollapsed = isCollapsed; - - // force command updating to happen. Slow, we'll speed it up later - // we could do this in JS, but we can't be a selection listener there - nsCOMPtr dispatcher; - nsresult rv = mChromeDoc->GetCommandDispatcher(getter_AddRefs(dispatcher)); - if (NS_FAILED(rv)) return rv; - if (!dispatcher) return NS_ERROR_UNEXPECTED; - - rv = dispatcher->UpdateCommands(nsAutoString("selection-change")); - if (NS_FAILED(rv)) return rv; } return ForceUpdate(); } +NS_IMETHODIMP nsInterfaceState::WillDo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidDo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aDoResult) +{ + // only need to update if the status of the Undo menu item changes. + PRInt32 undoCount; + aManager->GetNumberOfUndoItems(&undoCount); + if (undoCount == 1) + { + if (mFirstDoOfFirstUndo) + CallUpdateCommands(nsAutoString("undo")); + mFirstDoOfFirstUndo = PR_FALSE; + } + + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillUndo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidUndo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aUndoResult) +{ + PRInt32 undoCount; + aManager->GetNumberOfUndoItems(&undoCount); + if (undoCount == 0) + mFirstDoOfFirstUndo = PR_TRUE; // reset the state for the next do + + CallUpdateCommands(nsAutoString("undo")); + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillRedo(nsITransactionManager *aManager, + nsITransaction *aTransaction, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidRedo(nsITransactionManager *aManager, + nsITransaction *aTransaction, nsresult aRedoResult) +{ + CallUpdateCommands(nsAutoString("undo")); + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidBeginBatch(nsITransactionManager *aManager, nsresult aResult) +{ + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidEndBatch(nsITransactionManager *aManager, nsresult aResult) +{ + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::WillMerge(nsITransactionManager *aManager, + nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, PRBool *aInterrupt) +{ + *aInterrupt = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsInterfaceState::DidMerge(nsITransactionManager *aManager, + nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, + PRBool aDidMerge, nsresult aMergeResult) +{ + return NS_OK; +} + + +nsresult nsInterfaceState::CallUpdateCommands(const nsString& aCommand) +{ + if (!mDOMWindow) + { + nsCOMPtr editor = do_QueryInterface(mEditor); + if (!editor) return NS_ERROR_FAILURE; + + nsCOMPtr domDoc; + editor->GetDocument(getter_AddRefs(domDoc)); + if (!domDoc) return NS_ERROR_FAILURE; + + nsCOMPtr theDoc = do_QueryInterface(domDoc); + if (!theDoc) return NS_ERROR_FAILURE; + + nsCOMPtr scriptGlobalObject; + theDoc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); + + nsCOMPtr domWindow = do_QueryInterface(scriptGlobalObject); + if (!domWindow) return NS_ERROR_FAILURE; + mDOMWindow = domWindow; + } + + return mDOMWindow->UpdateCommands(aCommand); +} + NS_IMETHODIMP nsInterfaceState::ForceUpdate() { diff --git a/mozilla/editor/composer/src/nsInterfaceState.h b/mozilla/editor/composer/src/nsInterfaceState.h index dfd27b85055..dde6b6a40f8 100644 --- a/mozilla/editor/composer/src/nsInterfaceState.h +++ b/mozilla/editor/composer/src/nsInterfaceState.h @@ -27,6 +27,7 @@ #include "nsIDOMSelectionListener.h" #include "nsIDocumentStateListener.h" +#include "nsITransactionListener.h" #include "nsIWebShell.h" class nsIHTMLEditor; @@ -36,7 +37,8 @@ class nsIDOMXULDocument; // This is currently somewhat tied to a given XUL UI implementation class nsInterfaceState : public nsIDOMSelectionListener, - public nsIDocumentStateListener + public nsIDocumentStateListener, + public nsITransactionListener { public: @@ -57,6 +59,26 @@ public: NS_DECL_NSIDOCUMENTSTATELISTENER + + /** nsITransactionListener interfaces + */ + + NS_IMETHOD WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt); + NS_IMETHOD DidDo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aDoResult); + NS_IMETHOD WillUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt); + NS_IMETHOD DidUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aUndoResult); + NS_IMETHOD WillRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt); + NS_IMETHOD DidRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aRedoResult); + NS_IMETHOD WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt); + NS_IMETHOD DidBeginBatch(nsITransactionManager *aManager, nsresult aResult); + NS_IMETHOD WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt); + NS_IMETHOD DidEndBatch(nsITransactionManager *aManager, nsresult aResult); + NS_IMETHOD WillMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction, + nsITransaction *aTransactionToMerge, PRBool *aInterrupt); + NS_IMETHOD DidMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction, + nsITransaction *aTransactionToMerge, + PRBool aDidMerge, nsresult aMergeResult); + protected: enum { @@ -76,12 +98,16 @@ protected: nsresult UpdateFontFace(const char* observerName, const char* attributeName, nsString& ioFontString); nsresult UpdateDirtyState(PRBool aNowDirty); + nsresult CallUpdateCommands(const nsString& aCommand); + // this class should not hold references to the editor or editorShell. Doing // so would result in cirular reference chains. nsIHTMLEditor* mEditor; // the HTML editor nsIDOMXULDocument* mChromeDoc; // XUL document for the chrome area + nsIDOMWindow* mDOMWindow; // nsIDOMWindow used for calling UpdateCommands + // current state PRInt8 mBoldState; PRInt8 mItalicState; @@ -91,6 +117,7 @@ protected: PRInt8 mSelectionCollapsed; + PRPackedBool mFirstDoOfFirstUndo; nsString mParagraphFormat; nsString mFontString;