support for ChangeAttributeTxn

This commit is contained in:
buster%netscape.com 1999-01-06 20:29:11 +00:00
Родитель 23db7f64f8
Коммит af2c66d39a
8 изменённых файлов: 686 добавлений и 46 удалений

Просмотреть файл

@ -22,11 +22,15 @@
#include "nsIDOMEventReceiver.h"
#include "nsIDOMText.h"
#include "nsIDOMElement.h"
#include "nsIDOMAttr.h"
#include "nsIDocument.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
#include "nsEditFactory.h"
#include "nsEditorCID.h"
#include "nsTransactionManagerCID.h"
#include "nsITransactionManager.h"
#include "nsIAtom.h"
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
@ -41,6 +45,20 @@ static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kEditorCID, NS_EDITOR_CID);
static NS_DEFINE_IID(kITransactionManagerIID, NS_ITRANSACTIONMANAGER_IID);
static NS_DEFINE_CID(kCTransactionManagerFactoryCID, NS_TRANSACTION_MANAGER_FACTORY_CID);
#ifdef XP_PC
#define TRANSACTION_MANAGER_DLL "txmgr.dll"
#else
#ifdef XP_MAC
#define TRANSACTION_MANAGER_DLL "TRANSACTION_MANAGER_DLL"
#else // XP_UNIX
#define TRANSACTION_MANAGER_DLL "libtxmgr.so"
#endif
#endif
//monitor for the editor
@ -98,26 +116,29 @@ NSRegisterSelf(const char *path)
PR_TRUE, PR_TRUE); //this will register the factory with the xpcom dll.
}
extern "C" NS_EXPORT nsresult
NSUnregisterSelf(const char *path)
{
return nsRepository::UnregisterFactory(kIEditFactoryIID, path);//this will unregister the factory with the xpcom dll.
}
//END EXPORTS
//class implementations are in order they are declared in editor.h
static PRBool needsInit=PR_TRUE;
nsEditor::nsEditor()
{
//initialize member variables here
NS_INIT_REFCNT();
if (PR_TRUE==needsInit)
{
needsInit=PR_FALSE;
nsRepository::RegisterFactory(kCTransactionManagerFactoryCID,
TRANSACTION_MANAGER_DLL, PR_FALSE, PR_FALSE);
}
mTxnMgr = nsnull;
}
@ -210,6 +231,8 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
erP->AddEventListener(mKeyListenerP, kIDOMKeyListenerIID);
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
/* fire up the transaction manager */
/*
now to handle selection
*/
@ -229,6 +252,29 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
return t_result;
}
*/
nsISupports *isup = 0;
nsresult result;
result = nsServiceManager::GetService(kCTransactionManagerFactoryCID,
kITransactionManagerIID, &isup);
if (NS_FAILED(result) || !isup) {
printf("ERROR: Failed to get TransactionManager nsISupports interface.\n");
return NS_ERROR_OUT_OF_MEMORY;
}
result = isup->QueryInterface(kITransactionManagerIID, (void **)&mTxnMgr);
if (NS_FAILED(result)) {
printf("ERROR: Failed to get TransactionManager interface. (%d)\n", result);
return result;
}
if (!mTxnMgr) {
printf("ERROR: QueryInterface() returned NULL pointer.\n");
return NS_ERROR_NULL_POINTER;
}
return NS_OK;
}
@ -258,6 +304,40 @@ nsEditor::GetProperties(PROPERTIES **)
}
nsresult
nsEditor::SetAttribute(nsIDOMElement *aElement, const nsString& aAttribute, const nsString& aValue)
{
return aElement->SetDOMAttribute(aAttribute, aValue);
}
nsresult
nsEditor::GetAttributeValue(nsIDOMElement *aElement,
const nsString& aAttribute,
nsString& aResultValue,
PRBool& aResultIsSet)
{
aResultIsSet=PR_FALSE;
nsresult result=NS_OK;
if (nsnull!=aElement)
{
nsIDOMAttr* attNode=nsnull;
result = aElement->GetAttributeNode(aAttribute, &attNode);
if ((NS_SUCCEEDED(result)) && (nsnull!=attNode))
{
attNode->GetSpecified(&aResultIsSet);
attNode->GetValue(aResultValue);
}
}
return result;
}
nsresult
nsEditor::RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute)
{
return aElement->RemoveAttribute(aAttribute);
}
nsresult
nsEditor::Commit(PRBool aCtrlKey)
@ -337,6 +417,59 @@ nsEditor::GetCurrentNode(nsIDOMNode ** aNode)
return NS_ERROR_FAILURE;
}
nsresult
nsEditor::GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult)
{
nsresult result=NS_OK;
if (!aResult)
return NS_ERROR_NULL_POINTER;
/* If no node set, get root node */
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsIDOMElement> element;
if (nsnull==aStartNode)
{
mDomInterfaceP->GetDocumentElement(getter_AddRefs(element));
result = element->QueryInterface(kIDOMNodeIID,getter_AddRefs(node));
if (NS_FAILED(result))
return result;
if (!node)
return NS_ERROR_NULL_POINTER;
}
else
node=aStartNode;
*aResult = nsnull;
nsCOMPtr<nsIDOMNode> childNode;
result = node->GetFirstChild(getter_AddRefs(childNode));
while (childNode)
{
result = childNode->QueryInterface(kIDOMNodeIID,getter_AddRefs(element));
nsString tag;
if (NS_SUCCEEDED(result) && (element))
{
element->GetTagName(tag);
if (PR_TRUE==aTag.Equals(tag))
{
return (childNode->QueryInterface(kIDOMNodeIID,(void **) aResult)); // does the addref
}
else
{
nsresult result = GetFirstNodeOfType(childNode, aTag, aResult);
if (nsnull!=*aResult)
return result;
}
}
nsCOMPtr<nsIDOMNode> xNode;
childNode->GetNextSibling(getter_AddRefs(xNode));
childNode=xNode;
}
return NS_ERROR_FAILURE;
}
nsresult
@ -387,6 +520,46 @@ nsEditor::GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode)
return NS_OK;
}
nsresult
nsEditor::ExecuteTransaction(nsITransaction *aTxn)
{
nsresult result = NS_OK;
if (nsnull!=aTxn)
{
if (nsnull!=mTxnMgr)
{
result = mTxnMgr->Do(aTxn);
}
else
{
result = aTxn->Do();
}
}
return result;
}
nsresult
nsEditor::Undo()
{
nsresult result = NS_OK;
if (nsnull!=mTxnMgr)
{
result = mTxnMgr->Undo();
}
return result;
}
nsresult
nsEditor::Redo()
{
nsresult result = NS_OK;
if (nsnull!=mTxnMgr)
{
result = mTxnMgr->Redo();
}
return result;
}
//END nsEditor Private methods

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsIDOMEventListener.h"
#include "nsCOMPtr.h"
#include "editorInterfaces.h"
#include "nsITransactionManager.h"
//#include "nsISelection.h"
@ -42,6 +43,9 @@ private:
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
// nsCOMPtr<nsISelection> mSelectionP;
//nsCOMPtr<nsITransactionManager> mTxnMgrP;
nsITransactionManager * mTxnMgr;
public:
/** The default constructor. This should suffice. the setting of the interfaces is done
* after the construction of the editor class.
@ -66,10 +70,23 @@ public:
virtual nsresult GetProperties(PROPERTIES **);
virtual nsresult SetAttribute(nsIDOMElement * aElement,
const nsString& aAttribute,
const nsString& aValue);
virtual nsresult GetAttributeValue(nsIDOMElement * aElement,
const nsString& aAttribute,
nsString& aResultValue,
PRBool& aResultIsSet);
virtual nsresult RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
virtual nsresult InsertString(nsString *aString);
virtual nsresult Commit(PRBool aCtrlKey);
/*END nsIEditor interfaces*/
/*BEGIN nsEditor interfaces*/
@ -112,6 +129,42 @@ public:
*/
nsresult GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode);
/** GetFirstNodeOfType ADDREFFS and will get the next available node from the passed
* in aStartNode parameter of type aTag.
* It can also return NS_ERROR_FAILURE if no such nodes are available
* @param nsIDOMNode *aStartNode is the node to start looking from
* @param nsIAtom *aTag is the type of node we are searching for
* @param nsIDOMNode **aResult is the node we found, or nsnull if there is none
*/
nsresult GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult);
/** ExecuteTransaction fires a transaction. It is provided here so
* clients need no knowledge of whether the editor has a transaction manager or not.
* If a transaction manager is present, it is used.
* Otherwise, the transaction is just executed directly.
*
* @param aTxn the transaction to execute
*/
nsresult ExecuteTransaction(nsITransaction *aTxn);
/** Undo reverses the effects of the last ExecuteTransaction operation
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
* If a transaction manager is present, it is told to undo and the result of
* that undo is returned.
* Otherwise, the Undo request is ignored.
*
*/
nsresult Undo();
/** Redo reverses the effects of the last Undo operation
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
* If a transaction manager is present, it is told to redo and the result of
* that redo is returned.
* Otherwise, the Redo request is ignored.
*
*/
nsresult Redo();
/*END private methods of nsEditor*/
};

Просмотреть файл

@ -18,7 +18,11 @@
#include "editorInterfaces.h"
#include "nsString.h"
#include "editor.h"
#include "ChangeAttributeTxn.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
/*
* nsEditorKeyListener implementation
@ -113,25 +117,30 @@ nsEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
) {
switch(keyCode) {
case nsIDOMEvent::VK_BACK:
break;
case nsIDOMEvent::VK_RETURN:
// Need to implement creation of either <P> or <BR> nodes.
mEditor->Commit(ctrlKey);
break;
default:
// XXX Replace with x-platform NS-virtkeycode transform.
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
nsString* key = new nsString();
*key += character;
if (!isShift) {
key->ToLowerCase();
PRBool keyProcessed;
ProcessShortCutKeys(aKeyEvent, keyProcessed);
if (PR_FALSE==keyProcessed)
{
switch(keyCode) {
case nsIDOMEvent::VK_BACK:
break;
case nsIDOMEvent::VK_RETURN:
// Need to implement creation of either <P> or <BR> nodes.
mEditor->Commit(ctrlKey);
break;
default:
// XXX Replace with x-platform NS-virtkeycode transform.
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
nsString* key = new nsString();
*key += character;
if (!isShift) {
key->ToLowerCase();
}
mEditor->InsertString(key);
delete key;
}
mEditor->InsertString(key);
delete key;
break;
}
break;
}
}
@ -154,6 +163,90 @@ nsEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
return NS_OK;
}
nsresult
nsEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed)
{
aProcessed=PR_FALSE;
PRUint32 keyCode;
PRBool isShift;
PRBool ctrlKey;
if (NS_SUCCEEDED(aKeyEvent->GetKeyCode(&keyCode)) &&
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
)
{
// XXX: please please please get these mappings from an external source!
switch (keyCode)
{
// hard-coded undo
case nsIDOMEvent::VK_Z:
if (PR_TRUE==ctrlKey)
{
if (nsnull!=mEditor)
mEditor->Undo();
}
aProcessed=PR_TRUE;
break;
// hard-coded redo
case nsIDOMEvent::VK_Y:
if (PR_TRUE==ctrlKey)
{
if (nsnull!=mEditor)
mEditor->Redo();
}
aProcessed=PR_TRUE;
break;
case nsIDOMEvent::VK_TAB:
{
//XXX: should be from a factory
//XXX: should manage the refcount of txn
nsString attribute("width");
nsString value("400");
nsString tableTag("TABLE");
nsCOMPtr<nsIDOMNode> currentNode;
nsCOMPtr<nsIDOMElement> element;
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
{
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
{
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
mEditor->ExecuteTransaction(txn);
}
}
}
aProcessed=PR_TRUE;
break;
case nsIDOMEvent::VK_SPACE:
{
//XXX: should be from a factory
//XXX: should manage the refcount of txn
nsString attribute("height");
nsString value("200");
nsString tableTag("TABLE");
nsCOMPtr<nsIDOMNode> currentNode;
nsCOMPtr<nsIDOMElement> element;
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
{
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
{
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
mEditor->ExecuteTransaction(txn);
}
}
}
aProcessed=PR_TRUE;
break;
}
}
return NS_OK;
}
/*

Просмотреть файл

@ -65,6 +65,7 @@ public:
/*END interfaces from nsIDOMKeyListener*/
private:
virtual nsresult GetCharFromKeyCode(PRUint32 aKeyCode, PRBool aIsShift, char *aChar);
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
};

Просмотреть файл

@ -22,11 +22,15 @@
#include "nsIDOMEventReceiver.h"
#include "nsIDOMText.h"
#include "nsIDOMElement.h"
#include "nsIDOMAttr.h"
#include "nsIDocument.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
#include "nsEditFactory.h"
#include "nsEditorCID.h"
#include "nsTransactionManagerCID.h"
#include "nsITransactionManager.h"
#include "nsIAtom.h"
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
@ -41,6 +45,20 @@ static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kEditorCID, NS_EDITOR_CID);
static NS_DEFINE_IID(kITransactionManagerIID, NS_ITRANSACTIONMANAGER_IID);
static NS_DEFINE_CID(kCTransactionManagerFactoryCID, NS_TRANSACTION_MANAGER_FACTORY_CID);
#ifdef XP_PC
#define TRANSACTION_MANAGER_DLL "txmgr.dll"
#else
#ifdef XP_MAC
#define TRANSACTION_MANAGER_DLL "TRANSACTION_MANAGER_DLL"
#else // XP_UNIX
#define TRANSACTION_MANAGER_DLL "libtxmgr.so"
#endif
#endif
//monitor for the editor
@ -98,26 +116,29 @@ NSRegisterSelf(const char *path)
PR_TRUE, PR_TRUE); //this will register the factory with the xpcom dll.
}
extern "C" NS_EXPORT nsresult
NSUnregisterSelf(const char *path)
{
return nsRepository::UnregisterFactory(kIEditFactoryIID, path);//this will unregister the factory with the xpcom dll.
}
//END EXPORTS
//class implementations are in order they are declared in editor.h
static PRBool needsInit=PR_TRUE;
nsEditor::nsEditor()
{
//initialize member variables here
NS_INIT_REFCNT();
if (PR_TRUE==needsInit)
{
needsInit=PR_FALSE;
nsRepository::RegisterFactory(kCTransactionManagerFactoryCID,
TRANSACTION_MANAGER_DLL, PR_FALSE, PR_FALSE);
}
mTxnMgr = nsnull;
}
@ -210,6 +231,8 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
erP->AddEventListener(mKeyListenerP, kIDOMKeyListenerIID);
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
/* fire up the transaction manager */
/*
now to handle selection
*/
@ -229,6 +252,29 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
return t_result;
}
*/
nsISupports *isup = 0;
nsresult result;
result = nsServiceManager::GetService(kCTransactionManagerFactoryCID,
kITransactionManagerIID, &isup);
if (NS_FAILED(result) || !isup) {
printf("ERROR: Failed to get TransactionManager nsISupports interface.\n");
return NS_ERROR_OUT_OF_MEMORY;
}
result = isup->QueryInterface(kITransactionManagerIID, (void **)&mTxnMgr);
if (NS_FAILED(result)) {
printf("ERROR: Failed to get TransactionManager interface. (%d)\n", result);
return result;
}
if (!mTxnMgr) {
printf("ERROR: QueryInterface() returned NULL pointer.\n");
return NS_ERROR_NULL_POINTER;
}
return NS_OK;
}
@ -258,6 +304,40 @@ nsEditor::GetProperties(PROPERTIES **)
}
nsresult
nsEditor::SetAttribute(nsIDOMElement *aElement, const nsString& aAttribute, const nsString& aValue)
{
return aElement->SetDOMAttribute(aAttribute, aValue);
}
nsresult
nsEditor::GetAttributeValue(nsIDOMElement *aElement,
const nsString& aAttribute,
nsString& aResultValue,
PRBool& aResultIsSet)
{
aResultIsSet=PR_FALSE;
nsresult result=NS_OK;
if (nsnull!=aElement)
{
nsIDOMAttr* attNode=nsnull;
result = aElement->GetAttributeNode(aAttribute, &attNode);
if ((NS_SUCCEEDED(result)) && (nsnull!=attNode))
{
attNode->GetSpecified(&aResultIsSet);
attNode->GetValue(aResultValue);
}
}
return result;
}
nsresult
nsEditor::RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute)
{
return aElement->RemoveAttribute(aAttribute);
}
nsresult
nsEditor::Commit(PRBool aCtrlKey)
@ -337,6 +417,59 @@ nsEditor::GetCurrentNode(nsIDOMNode ** aNode)
return NS_ERROR_FAILURE;
}
nsresult
nsEditor::GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult)
{
nsresult result=NS_OK;
if (!aResult)
return NS_ERROR_NULL_POINTER;
/* If no node set, get root node */
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsIDOMElement> element;
if (nsnull==aStartNode)
{
mDomInterfaceP->GetDocumentElement(getter_AddRefs(element));
result = element->QueryInterface(kIDOMNodeIID,getter_AddRefs(node));
if (NS_FAILED(result))
return result;
if (!node)
return NS_ERROR_NULL_POINTER;
}
else
node=aStartNode;
*aResult = nsnull;
nsCOMPtr<nsIDOMNode> childNode;
result = node->GetFirstChild(getter_AddRefs(childNode));
while (childNode)
{
result = childNode->QueryInterface(kIDOMNodeIID,getter_AddRefs(element));
nsString tag;
if (NS_SUCCEEDED(result) && (element))
{
element->GetTagName(tag);
if (PR_TRUE==aTag.Equals(tag))
{
return (childNode->QueryInterface(kIDOMNodeIID,(void **) aResult)); // does the addref
}
else
{
nsresult result = GetFirstNodeOfType(childNode, aTag, aResult);
if (nsnull!=*aResult)
return result;
}
}
nsCOMPtr<nsIDOMNode> xNode;
childNode->GetNextSibling(getter_AddRefs(xNode));
childNode=xNode;
}
return NS_ERROR_FAILURE;
}
nsresult
@ -387,6 +520,46 @@ nsEditor::GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode)
return NS_OK;
}
nsresult
nsEditor::ExecuteTransaction(nsITransaction *aTxn)
{
nsresult result = NS_OK;
if (nsnull!=aTxn)
{
if (nsnull!=mTxnMgr)
{
result = mTxnMgr->Do(aTxn);
}
else
{
result = aTxn->Do();
}
}
return result;
}
nsresult
nsEditor::Undo()
{
nsresult result = NS_OK;
if (nsnull!=mTxnMgr)
{
result = mTxnMgr->Undo();
}
return result;
}
nsresult
nsEditor::Redo()
{
nsresult result = NS_OK;
if (nsnull!=mTxnMgr)
{
result = mTxnMgr->Redo();
}
return result;
}
//END nsEditor Private methods

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsIDOMEventListener.h"
#include "nsCOMPtr.h"
#include "editorInterfaces.h"
#include "nsITransactionManager.h"
//#include "nsISelection.h"
@ -42,6 +43,9 @@ private:
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
// nsCOMPtr<nsISelection> mSelectionP;
//nsCOMPtr<nsITransactionManager> mTxnMgrP;
nsITransactionManager * mTxnMgr;
public:
/** The default constructor. This should suffice. the setting of the interfaces is done
* after the construction of the editor class.
@ -66,10 +70,23 @@ public:
virtual nsresult GetProperties(PROPERTIES **);
virtual nsresult SetAttribute(nsIDOMElement * aElement,
const nsString& aAttribute,
const nsString& aValue);
virtual nsresult GetAttributeValue(nsIDOMElement * aElement,
const nsString& aAttribute,
nsString& aResultValue,
PRBool& aResultIsSet);
virtual nsresult RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
virtual nsresult InsertString(nsString *aString);
virtual nsresult Commit(PRBool aCtrlKey);
/*END nsIEditor interfaces*/
/*BEGIN nsEditor interfaces*/
@ -112,6 +129,42 @@ public:
*/
nsresult GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode);
/** GetFirstNodeOfType ADDREFFS and will get the next available node from the passed
* in aStartNode parameter of type aTag.
* It can also return NS_ERROR_FAILURE if no such nodes are available
* @param nsIDOMNode *aStartNode is the node to start looking from
* @param nsIAtom *aTag is the type of node we are searching for
* @param nsIDOMNode **aResult is the node we found, or nsnull if there is none
*/
nsresult GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult);
/** ExecuteTransaction fires a transaction. It is provided here so
* clients need no knowledge of whether the editor has a transaction manager or not.
* If a transaction manager is present, it is used.
* Otherwise, the transaction is just executed directly.
*
* @param aTxn the transaction to execute
*/
nsresult ExecuteTransaction(nsITransaction *aTxn);
/** Undo reverses the effects of the last ExecuteTransaction operation
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
* If a transaction manager is present, it is told to undo and the result of
* that undo is returned.
* Otherwise, the Undo request is ignored.
*
*/
nsresult Undo();
/** Redo reverses the effects of the last Undo operation
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
* If a transaction manager is present, it is told to redo and the result of
* that redo is returned.
* Otherwise, the Redo request is ignored.
*
*/
nsresult Redo();
/*END private methods of nsEditor*/
};

Просмотреть файл

@ -18,7 +18,11 @@
#include "editorInterfaces.h"
#include "nsString.h"
#include "editor.h"
#include "ChangeAttributeTxn.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
/*
* nsEditorKeyListener implementation
@ -113,25 +117,30 @@ nsEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
) {
switch(keyCode) {
case nsIDOMEvent::VK_BACK:
break;
case nsIDOMEvent::VK_RETURN:
// Need to implement creation of either <P> or <BR> nodes.
mEditor->Commit(ctrlKey);
break;
default:
// XXX Replace with x-platform NS-virtkeycode transform.
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
nsString* key = new nsString();
*key += character;
if (!isShift) {
key->ToLowerCase();
PRBool keyProcessed;
ProcessShortCutKeys(aKeyEvent, keyProcessed);
if (PR_FALSE==keyProcessed)
{
switch(keyCode) {
case nsIDOMEvent::VK_BACK:
break;
case nsIDOMEvent::VK_RETURN:
// Need to implement creation of either <P> or <BR> nodes.
mEditor->Commit(ctrlKey);
break;
default:
// XXX Replace with x-platform NS-virtkeycode transform.
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
nsString* key = new nsString();
*key += character;
if (!isShift) {
key->ToLowerCase();
}
mEditor->InsertString(key);
delete key;
}
mEditor->InsertString(key);
delete key;
break;
}
break;
}
}
@ -154,6 +163,90 @@ nsEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
return NS_OK;
}
nsresult
nsEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed)
{
aProcessed=PR_FALSE;
PRUint32 keyCode;
PRBool isShift;
PRBool ctrlKey;
if (NS_SUCCEEDED(aKeyEvent->GetKeyCode(&keyCode)) &&
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
)
{
// XXX: please please please get these mappings from an external source!
switch (keyCode)
{
// hard-coded undo
case nsIDOMEvent::VK_Z:
if (PR_TRUE==ctrlKey)
{
if (nsnull!=mEditor)
mEditor->Undo();
}
aProcessed=PR_TRUE;
break;
// hard-coded redo
case nsIDOMEvent::VK_Y:
if (PR_TRUE==ctrlKey)
{
if (nsnull!=mEditor)
mEditor->Redo();
}
aProcessed=PR_TRUE;
break;
case nsIDOMEvent::VK_TAB:
{
//XXX: should be from a factory
//XXX: should manage the refcount of txn
nsString attribute("width");
nsString value("400");
nsString tableTag("TABLE");
nsCOMPtr<nsIDOMNode> currentNode;
nsCOMPtr<nsIDOMElement> element;
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
{
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
{
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
mEditor->ExecuteTransaction(txn);
}
}
}
aProcessed=PR_TRUE;
break;
case nsIDOMEvent::VK_SPACE:
{
//XXX: should be from a factory
//XXX: should manage the refcount of txn
nsString attribute("height");
nsString value("200");
nsString tableTag("TABLE");
nsCOMPtr<nsIDOMNode> currentNode;
nsCOMPtr<nsIDOMElement> element;
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
{
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
{
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
mEditor->ExecuteTransaction(txn);
}
}
}
aProcessed=PR_TRUE;
break;
}
}
return NS_OK;
}
/*

Просмотреть файл

@ -65,6 +65,7 @@ public:
/*END interfaces from nsIDOMKeyListener*/
private:
virtual nsresult GetCharFromKeyCode(PRUint32 aKeyCode, PRBool aIsShift, char *aChar);
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
};