From 8791c2aa99949a447afb25e8fd7e7380e0f8734d Mon Sep 17 00:00:00 2001 From: "pollmann%netscape.com" Date: Wed, 15 Sep 1999 05:31:31 +0000 Subject: [PATCH] Bug 13058: (Fixed Solaris bustage by removing Inherited typedef) git-svn-id: svn://10.0.0.236/trunk@47538 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/forms/nsComboboxControlFrame.cpp | 96 +++++-- mozilla/layout/forms/nsComboboxControlFrame.h | 11 +- mozilla/layout/forms/nsFileControlFrame.cpp | 91 ++++++- mozilla/layout/forms/nsFileControlFrame.h | 10 +- mozilla/layout/forms/nsISelectControlFrame.h | 2 + mozilla/layout/forms/nsListControlFrame.cpp | 94 ++++++- mozilla/layout/forms/nsListControlFrame.h | 10 +- mozilla/layout/forms/nsTextControlFrame.cpp | 64 +++++ mozilla/layout/forms/nsTextControlFrame.h | 15 +- .../html/forms/public/nsISelectControlFrame.h | 2 + .../html/forms/src/nsCheckboxControlFrame.cpp | 72 ++++- .../html/forms/src/nsCheckboxControlFrame.h | 21 +- .../html/forms/src/nsComboboxControlFrame.cpp | 96 +++++-- .../html/forms/src/nsComboboxControlFrame.h | 11 +- .../html/forms/src/nsFileControlFrame.cpp | 91 ++++++- .../html/forms/src/nsFileControlFrame.h | 10 +- .../html/forms/src/nsListControlFrame.cpp | 94 ++++++- .../html/forms/src/nsListControlFrame.h | 10 +- .../forms/src/nsNativeFormControlFrame.cpp | 12 +- .../html/forms/src/nsNativeFormControlFrame.h | 3 - .../forms/src/nsNativeSelectControlFrame.cpp | 252 +++++++++++++----- .../forms/src/nsNativeTextControlFrame.cpp | 43 ++- .../html/forms/src/nsNativeTextControlFrame.h | 10 +- .../html/forms/src/nsRadioControlFrame.cpp | 63 ++++- .../html/forms/src/nsRadioControlFrame.h | 14 +- .../html/forms/src/nsTextControlFrame.cpp | 64 +++++ .../html/forms/src/nsTextControlFrame.h | 15 +- 27 files changed, 1096 insertions(+), 180 deletions(-) diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index df6ba61febe..dc392aef9a5 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -38,11 +38,14 @@ #include "nsIDeviceContext.h" #include "nsIView.h" #include "nsIScrollableView.h" - #include "nsIEventStateManager.h" -// Get onChange to target Select not Option #include "nsIDOMNode.h" #include "nsIPrivateDOMEvent.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsArray.h" +#include "nsISelectControlFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID); @@ -148,11 +151,15 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; return NS_OK; - } else if (aIID.Equals(nsCOMTypeInfo::GetIID())) { - *aInstancePtr = (void *)((nsISelectControlFrame*)this); + } else if (aIID.Equals(NS_GET_IID(nsISelectControlFrame))) { + *aInstancePtr = (void *)(nsISelectControlFrame*)this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void *)(nsIStatefulFrame*)this; + NS_ADDREF_THIS(); return NS_OK; } - return nsAreaFrame::QueryInterface(aIID, aInstancePtr); } @@ -1042,16 +1049,16 @@ nsComboboxControlFrame::SelectionChanged(PRBool aDoDispatchEvent) nsIDOMNode* node = nsnull; res = mContent->QueryInterface(kIDOMNodeIID, (void**)&node); if (NS_SUCCEEDED(res) && node) { - nsIPrivateDOMEvent* pDOMEvent = nsnull; + nsIPrivateDOMEvent* pDOMEvent = nsnull; res = DOMEvent->QueryInterface(kIPrivateDOMEventIID, (void**)&pDOMEvent); if (NS_SUCCEEDED(res) && pDOMEvent) { pDOMEvent->SetTarget(node); - NS_RELEASE(pDOMEvent); + NS_RELEASE(pDOMEvent); // Have the content handle the event. mContent->HandleDOMEvent(*mPresContext, &event, &DOMEvent, NS_EVENT_FLAG_BUBBLE, status); } - NS_RELEASE(node); + NS_RELEASE(node); } NS_RELEASE(DOMEvent); } @@ -1077,10 +1084,11 @@ nsComboboxControlFrame::AddOption(PRInt32 aIndex) { nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); - nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo::GetIID(), + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); - if (NS_SUCCEEDED(rv) && nsnull != listFrame) { - return listFrame->AddOption(aIndex); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->AddOption(aIndex); + NS_RELEASE(listFrame); } return rv; } @@ -1091,10 +1099,11 @@ nsComboboxControlFrame::RemoveOption(PRInt32 aIndex) { nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); - nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo::GetIID(), + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); - if (NS_SUCCEEDED(rv) && nsnull != listFrame) { - return listFrame->RemoveOption(aIndex); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->RemoveOption(aIndex); + NS_RELEASE(listFrame); } return rv; } @@ -1104,10 +1113,25 @@ nsComboboxControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) { nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); - nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo::GetIID(), + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); - if (NS_SUCCEEDED(rv) && nsnull != listFrame) { - return listFrame->SetOptionSelected(aIndex, aValue); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->SetOptionSelected(aIndex, aValue); + NS_RELEASE(listFrame); + } + return rv; +} + +NS_IMETHODIMP +nsComboboxControlFrame::GetOptionSelected(PRInt32 aIndex, PRBool* aValue) +{ + nsISelectControlFrame* listFrame = nsnull; + nsIFrame* dropdownFrame = GetDropdownFrame(); + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), + (void**)&listFrame); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->GetOptionSelected(aIndex, aValue); + NS_RELEASE(listFrame); } return rv; } @@ -1368,4 +1392,42 @@ nsComboboxControlFrame::Blur(nsIDOMEvent* aEvent) return NS_OK; } +//---------------------------------------------------------------------- +// nsIStatefulFrame +// XXX Do we need to implement this here? It is already implemented in +// the ListControlFrame, our child... +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsComboboxControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eSelectType; + return NS_OK; +} +NS_IMETHODIMP +nsComboboxControlFrame::SaveState(nsISupports** aState) +{ + if (!mListControlFrame) return NS_ERROR_UNEXPECTED; + nsIStatefulFrame* sFrame = nsnull; + nsresult res = mListControlFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), + (void**)&sFrame); + if (NS_SUCCEEDED(res) && sFrame) { + res = sFrame->SaveState(aState); + NS_RELEASE(sFrame); + } + return res; +} + +NS_IMETHODIMP +nsComboboxControlFrame::RestoreState(nsISupports* aState) +{ + if (!mListControlFrame) return NS_ERROR_UNEXPECTED; + nsIStatefulFrame* sFrame = nsnull; + nsresult res = mListControlFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), + (void**)&sFrame); + if (NS_SUCCEEDED(res) && sFrame) { + res = sFrame->RestoreState(aState); + NS_RELEASE(sFrame); + } + return res; +} diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h index a8aed6e33b8..e63a511827b 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.h +++ b/mozilla/layout/forms/nsComboboxControlFrame.h @@ -28,6 +28,7 @@ #include "nsVoidArray.h" #include "nsIAnonymousContentCreator.h" #include "nsISelectControlFrame.h" +#include "nsIStatefulFrame.h" class nsButtonControlFrame; class nsTextControlFrame; @@ -49,8 +50,8 @@ class nsComboboxControlFrame : public nsAreaFrame, public nsIDOMMouseListener, public nsIDOMFocusListener, public nsIAnonymousContentCreator, - public nsISelectControlFrame - + public nsISelectControlFrame, + public nsIStatefulFrame { public: nsComboboxControlFrame(); @@ -140,6 +141,7 @@ public: NS_IMETHOD AddOption(PRInt32 index); NS_IMETHOD RemoveOption(PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); + NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); //nsIDOMEventListener virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); @@ -154,6 +156,11 @@ public: virtual nsresult Focus(nsIDOMEvent* aEvent); virtual nsresult Blur(nsIDOMEvent* aEvent); + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); + protected: // nsHTMLContainerFrame diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index b9db0c8aa0e..c263f53a4e6 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -45,7 +45,9 @@ #include "nsIDOMMouseListener.h" #include "nsIPresShell.h" #include "nsIDOMHTMLInputElement.h" - +#include "nsIStatefulFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID); static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID); @@ -76,11 +78,16 @@ nsFileControlFrame::nsFileControlFrame(): { //Shrink the area around it's contents SetFlags(NS_BLOCK_SHRINK_WRAP); + mCachedState = nsnull; } nsFileControlFrame::~nsFileControlFrame() { NS_IF_RELEASE(mTextContent); + if (mCachedState) { + delete mCachedState; + mCachedState = nsnull; + } } NS_IMETHODIMP @@ -121,25 +128,28 @@ nsFileControlFrame::CreateAnonymousContent(nsISupportsArray& aChildList) return NS_OK; } -nsresult +NS_IMETHODIMP nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) { NS_PRECONDITION(0 != aInstancePtr, "null ptr"); if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { - *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; - NS_ADDREF_THIS(); - return NS_OK; + } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; } else if (aIID.Equals(kIFormControlFrameIID)) { *aInstancePtr = (void*) ((nsIFormControlFrame*) this); return NS_OK; - } else if (aIID.Equals(kIDOMMouseListenerIID)) { - *aInstancePtr = (void*)(nsIDOMMouseListener*) this; - NS_ADDREF_THIS(); - return NS_OK; - } - + } else if (aIID.Equals(kIDOMMouseListenerIID)) { + *aInstancePtr = (void*)(nsIDOMMouseListener*) this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); } @@ -260,6 +270,12 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext, // add ourself as an nsIFormControlFrame nsFormFrame::AddFormControlFrame(aPresContext, *this); mTextFrame = GetTextControlFrame(this); + if (!mTextFrame) return NS_ERROR_UNEXPECTED; + if (mCachedState) { + mTextFrame->SetProperty(nsHTMLAtoms::value, *mCachedState); + delete mCachedState; + mCachedState = nsnull; + } } return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); @@ -291,7 +307,7 @@ nsFileControlFrame::GetTextControlFrame(nsIFrame* aStart) nsIFrame* childFrame = nsnull; aStart->FirstChild(nsnull, &childFrame); - while (nsnull != childFrame) { + while (childFrame) { // see if the child is a text control nsCOMPtr content; childFrame->GetContent(getter_AddRefs(content)); @@ -308,7 +324,7 @@ nsFileControlFrame::GetTextControlFrame(nsIFrame* aStart) // if not continue looking nsTextControlFrame* frame = GetTextControlFrame(childFrame); - if (frame != nsnull) + if (frame) return frame; nsresult rv = childFrame->GetNextSibling(&childFrame); @@ -486,3 +502,50 @@ nsFileControlFrame::Paint(nsIPresContext& aPresContext, { return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsFileControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eFileType; + return NS_OK; +} + +NS_IMETHODIMP +nsFileControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsString* value = nsnull; + nsAutoString string; + nsresult res = mTextFrame->GetProperty(nsHTMLAtoms::value, string); + if (NS_SUCCEEDED(res)) { + char* chars = string.ToNewCString(); + if (chars) { + res = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), (void**)&value); + if (NS_SUCCEEDED(res) && value) { + value->SetData(chars); + } + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + } + *aState = (nsISupports*)value; + return res; +} + +NS_IMETHODIMP +nsFileControlFrame::RestoreState(nsISupports* aState) +{ + char* chars = nsnull; + nsresult res = ((nsISupportsString*)aState)->GetData(&chars); + if (NS_SUCCEEDED(res) && chars) { + // Don't poke mTextFrame, it's not there yet. + mCachedState = new nsString(chars); + if (!mCachedState) res = NS_ERROR_OUT_OF_MEMORY; + nsCRT::free(chars); + } + return res; +} diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h index a49ab236f33..12efcab41ca 100644 --- a/mozilla/layout/forms/nsFileControlFrame.h +++ b/mozilla/layout/forms/nsFileControlFrame.h @@ -23,6 +23,7 @@ #include "nsIFormControlFrame.h" #include "nsIDOMMouseListener.h" #include "nsIAnonymousContentCreator.h" +#include "nsIStatefulFrame.h" class nsButtonControlFrame; class nsTextControlFrame; @@ -33,7 +34,8 @@ class nsIHTMLContent; class nsFileControlFrame : public nsAreaFrame, public nsIFormControlFrame, public nsIDOMMouseListener, - public nsIAnonymousContentCreator + public nsIAnonymousContentCreator, + public nsIStatefulFrame { public: @@ -144,6 +146,11 @@ public: virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); + protected: nsIWidget* GetWindowTemp(nsIView *aView); // XXX temporary @@ -152,6 +159,7 @@ protected: nsTextControlFrame* mTextFrame; nsFormFrame* mFormFrame; nsIHTMLContent* mTextContent; + nsString* mCachedState; private: nsTextControlFrame* GetTextControlFrame(nsIFrame* aStart); diff --git a/mozilla/layout/forms/nsISelectControlFrame.h b/mozilla/layout/forms/nsISelectControlFrame.h index 87427eb7bf1..8027a679e95 100644 --- a/mozilla/layout/forms/nsISelectControlFrame.h +++ b/mozilla/layout/forms/nsISelectControlFrame.h @@ -52,6 +52,8 @@ public: */ NS_IMETHOD SetOptionSelected(PRInt32 index, PRBool value) = 0; + + NS_IMETHOD GetOptionSelected(PRInt32 index, PRBool* value) = 0; }; #endif diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index 97caa4a8d30..2071d269a68 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -37,10 +37,13 @@ #include "nsIReflowCommand.h" #include "nsIPresShell.h" #include "nsHTMLParts.h" - #include "nsIDOMEventReceiver.h" #include "nsIEventStateManager.h" #include "nsIDOMUIEvent.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsArray.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID); static NS_DEFINE_IID(kIDOMMouseMotionListenerIID, NS_IDOMMOUSEMOTIONLISTENER_IID); @@ -150,6 +153,11 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_ADDREF_THIS(); return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } return nsScrollFrame::QueryInterface(aIID, aInstancePtr); } @@ -1637,6 +1645,15 @@ nsListControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) return NS_OK; } +//--------------------------------------------------------- +// Determine if the specified item in the listbox is selected. +NS_IMETHODIMP +nsListControlFrame::GetOptionSelected(PRInt32 aIndex, PRBool* aValue) +{ + *aValue = IsContentSelectedByIndex(aIndex); + return NS_OK; +} + //---------------------------------------------------------------------- // End nsISelectControlFrame //---------------------------------------------------------------------- @@ -2150,3 +2167,78 @@ nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) return NS_OK; } +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsListControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eSelectType; + return NS_OK; +} + +NS_IMETHODIMP +nsListControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsArray* value = nsnull; + nsresult res = NS_NewISupportsArray(&value); + if (NS_SUCCEEDED(res) && value) { + PRInt32 j=0; + PRInt32 length = 0; + GetNumberOfOptions(&length); + PRInt32 i; + for (i=0; iSetData(i); + if (NS_SUCCEEDED(res)) { + PRBool okay = value->InsertElementAt((nsISupports *)thisVal, j++); + if (!okay) res = NS_ERROR_OUT_OF_MEMORY; // Most likely cause; + } + if (!NS_SUCCEEDED(res)) NS_RELEASE(thisVal); + } + } + if (!NS_SUCCEEDED(res)) break; + } + if (iCount(&count); + if (NS_SUCCEEDED(res)) { + nsISupportsPRInt32* thisVal = nsnull; + PRInt32 j=0; + for (PRUint32 i=0; iElementAt(i); + if (thisVal) { + res = thisVal->GetData(&j); + if (NS_SUCCEEDED(res)) { + res = SetOptionSelected(j, PR_TRUE); + } + } else { + res = NS_ERROR_UNEXPECTED; + } + if (!NS_SUCCEEDED(res)) break; + } + } + } + } + return res; +} diff --git a/mozilla/layout/forms/nsListControlFrame.h b/mozilla/layout/forms/nsListControlFrame.h index fccf099fe46..24581a604c7 100644 --- a/mozilla/layout/forms/nsListControlFrame.h +++ b/mozilla/layout/forms/nsListControlFrame.h @@ -26,6 +26,7 @@ #include "nsIDOMMouseListener.h" #include "nsIDOMMouseMotionListener.h" #include "nsIDOMKeyListener.h" +#include "nsIStatefulFrame.h" class nsIDOMHTMLSelectElement; class nsIDOMHTMLCollection; @@ -44,7 +45,8 @@ class nsListControlFrame : public nsScrollFrame, public nsIDOMMouseListener, public nsIDOMMouseMotionListener, public nsIDOMKeyListener, - public nsISelectControlFrame + public nsISelectControlFrame, + public nsIStatefulFrame { public: friend nsresult NS_NewListControlFrame(nsIFrame** aNewFrame); @@ -120,6 +122,12 @@ public: NS_IMETHOD AddOption(PRInt32 index); NS_IMETHOD RemoveOption(PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); + NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); //nsIDOMEventListener virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); diff --git a/mozilla/layout/forms/nsTextControlFrame.cpp b/mozilla/layout/forms/nsTextControlFrame.cpp index 8bd0417bb75..8ec3a4ca4c1 100644 --- a/mozilla/layout/forms/nsTextControlFrame.cpp +++ b/mozilla/layout/forms/nsTextControlFrame.cpp @@ -45,6 +45,9 @@ #include "nsIFontMetrics.h" #include "nsILookAndFeel.h" #include "nsIComponentManager.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID); @@ -67,6 +70,21 @@ nsTextControlFrame::~nsTextControlFrame() { } +nsresult +nsTextControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_PRECONDITION(0 != aInstancePtr, "null ptr"); + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} + nscoord nsTextControlFrame::GetVerticalBorderWidth(float aPixToTwip) const { @@ -355,3 +373,49 @@ nsTextControlFrame::GetWrapProperty(nsString &aOutValue) } return result; } + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsTextControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eTextType; + return NS_OK; +} + +NS_IMETHODIMP +nsTextControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsString* value = nsnull; + nsAutoString string; + nsresult res = GetProperty(nsHTMLAtoms::value, string); + if (NS_SUCCEEDED(res)) { + char* chars = string.ToNewCString(); + if (chars) { + res = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), (void**)&value); + if (NS_SUCCEEDED(res) && value) { + value->SetData(chars); + } + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + } + *aState = (nsISupports*)value; + return res; +} + +NS_IMETHODIMP +nsTextControlFrame::RestoreState(nsISupports* aState) +{ + char* chars = nsnull; + nsresult res = ((nsISupportsString*)aState)->GetData(&chars); + if (NS_SUCCEEDED(res) && chars) { + nsAutoString string(chars); + res = SetProperty(nsHTMLAtoms::value, string); + nsCRT::free(chars); + } + return res; +} diff --git a/mozilla/layout/forms/nsTextControlFrame.h b/mozilla/layout/forms/nsTextControlFrame.h index 953ef90653e..9395d485755 100644 --- a/mozilla/layout/forms/nsTextControlFrame.h +++ b/mozilla/layout/forms/nsTextControlFrame.h @@ -20,11 +20,14 @@ #define nsTextControlFrame_h___ #include "nsNativeFormControlFrame.h" +#include "nsIStatefulFrame.h" + class nsIContent; class nsIFrame; class nsIPresContext; -class nsTextControlFrame : public nsNativeFormControlFrame +class nsTextControlFrame : public nsNativeFormControlFrame, + public nsIStatefulFrame { /* ---------- methods implemented by base class ---------- */ public: @@ -34,6 +37,8 @@ public: virtual const nsIID& GetCID(); virtual const nsIID& GetIID(); + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD GetFrameName(nsString& aResult) const; virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const; @@ -53,6 +58,11 @@ public: * returns NS_CONTENT_ATTR_NOT_THERE if the property does not exist for this */ NS_IMETHOD GetWrapProperty(nsString &aOutValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); protected: @@ -67,6 +77,9 @@ protected: PRInt32 GetDefaultColumnWidth() const { return (PRInt32)(20); } // this was DEFAULT_PIXEL_WIDTH +private: + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } /* ---------- abstract methods derived class must implement ---------- */ diff --git a/mozilla/layout/html/forms/public/nsISelectControlFrame.h b/mozilla/layout/html/forms/public/nsISelectControlFrame.h index 87427eb7bf1..8027a679e95 100644 --- a/mozilla/layout/html/forms/public/nsISelectControlFrame.h +++ b/mozilla/layout/html/forms/public/nsISelectControlFrame.h @@ -52,6 +52,8 @@ public: */ NS_IMETHOD SetOptionSelected(PRInt32 index, PRBool value) = 0; + + NS_IMETHOD GetOptionSelected(PRInt32 index, PRBool* value) = 0; }; #endif diff --git a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp index 39c94630fa9..e71d00ce852 100644 --- a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp @@ -25,8 +25,28 @@ #include "nsCOMPtr.h" #include "nsINameSpaceManager.h" #include "nsFormFrame.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" +//---------------------------------------------------------------------- +// nsISupports +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsCheckboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!"); + if ( !aInstancePtr ) + return NS_ERROR_NULL_POINTER; + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} + // // GetTristateAtom [static] // @@ -82,7 +102,7 @@ nsCheckboxControlFrame::Init(nsIPresContext& aPresContext, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { - Inherited::Init ( aPresContext, aContent, aParent, aContext, aPrevInFlow ); + nsNativeFormControlFrame::Init ( aPresContext, aContent, aParent, aContext, aPrevInFlow ); // figure out if we're a tristate at the start. This may change later on once // we've been running for a while, so more code is in AttributeChanged() to pick @@ -164,7 +184,7 @@ nsCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext, } } else - return Inherited::AttributeChanged(aPresContext, aChild, aAttribute, aHint); + return nsNativeFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint); return NS_OK; } @@ -257,7 +277,7 @@ NS_METHOD nsCheckboxControlFrame::HandleEvent(nsIPresContext& aPresContext, if (nsFormFrame::GetDisabled(this)) return NS_OK; - return(Inherited::HandleEvent(aPresContext, aEvent, aEventStatus)); + return(nsNativeFormControlFrame::HandleEvent(aPresContext, aEvent, aEventStatus)); } @@ -278,7 +298,7 @@ NS_IMETHODIMP nsCheckboxControlFrame::SetProperty(nsIAtom* aName, const nsString if (nsHTMLAtoms::checked == aName) SetCheckboxControlFrameState(aValue); else - return Inherited::SetProperty(aName, aValue); + return nsNativeFormControlFrame::SetProperty(aName, aValue); return NS_OK; } @@ -289,7 +309,7 @@ NS_IMETHODIMP nsCheckboxControlFrame::GetProperty(nsIAtom* aName, nsString& aVal if (nsHTMLAtoms::checked == aName) GetCheckboxControlFrameState(aValue); else - return Inherited::GetProperty(aName, aValue); + return nsNativeFormControlFrame::GetProperty(aName, aValue); return NS_OK; } @@ -376,3 +396,45 @@ nsCheckboxControlFrame :: SwitchModesWithEmergencyBrake ( PRBool inIsNowTristate mIsTristate = inIsNowTristate; } // SwitchModesWithEmergencyBrake + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP nsCheckboxControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType=nsIStatefulFrame::eCheckboxType; + return NS_OK; +} + +NS_IMETHODIMP nsCheckboxControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsString* value = nsnull; + nsresult res = NS_OK; + nsAutoString string; + GetCheckboxControlFrameState(string); + char* chars = string.ToNewCString(); + if (chars) { + res = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), (void**)&value); + if (NS_SUCCEEDED(res) && value) { + value->SetData(chars); + } + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + *aState = (nsISupports*)value; + return res; +} + +NS_IMETHODIMP nsCheckboxControlFrame::RestoreState(nsISupports* aState) +{ + char* chars = nsnull; + nsresult res = ((nsISupportsString*)aState)->GetData(&chars); + if (NS_SUCCEEDED(res) && chars) { + nsAutoString string(chars); + SetCheckboxControlFrameState(string); + nsCRT::free(chars); + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h index 35e58839867..6ef1c7f1bc5 100644 --- a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h @@ -19,6 +19,7 @@ #define nsCheckboxControlFrame_h___ #include "nsNativeFormControlFrame.h" +#include "nsIStatefulFrame.h" // // nsCheckboxControlFrame @@ -40,10 +41,9 @@ // become checked since "mixed" doesn't exist on normal checkboxes. // -class nsCheckboxControlFrame : public nsNativeFormControlFrame { -private: - typedef nsNativeFormControlFrame Inherited; - +class nsCheckboxControlFrame : public nsNativeFormControlFrame, + public nsIStatefulFrame +{ public: nsCheckboxControlFrame ( ) ; @@ -84,9 +84,15 @@ public: nsGUIEvent* aEvent, nsEventStatus& aEventStatus); - // this should be protected, but VC6 is lame. + // this should be protected, but VC6 is lame. enum CheckState { eOff, eOn, eMixed } ; - + + // nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + protected: // native/gfx implementations need to implement needs. @@ -114,6 +120,9 @@ protected: static nsIAtom* GetTristateAtom() ; static nsIAtom* GetTristateValueAtom() ; +private: + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } }; // class nsCheckboxControlFrame #endif diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index df6ba61febe..dc392aef9a5 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -38,11 +38,14 @@ #include "nsIDeviceContext.h" #include "nsIView.h" #include "nsIScrollableView.h" - #include "nsIEventStateManager.h" -// Get onChange to target Select not Option #include "nsIDOMNode.h" #include "nsIPrivateDOMEvent.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsArray.h" +#include "nsISelectControlFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID); @@ -148,11 +151,15 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; return NS_OK; - } else if (aIID.Equals(nsCOMTypeInfo::GetIID())) { - *aInstancePtr = (void *)((nsISelectControlFrame*)this); + } else if (aIID.Equals(NS_GET_IID(nsISelectControlFrame))) { + *aInstancePtr = (void *)(nsISelectControlFrame*)this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void *)(nsIStatefulFrame*)this; + NS_ADDREF_THIS(); return NS_OK; } - return nsAreaFrame::QueryInterface(aIID, aInstancePtr); } @@ -1042,16 +1049,16 @@ nsComboboxControlFrame::SelectionChanged(PRBool aDoDispatchEvent) nsIDOMNode* node = nsnull; res = mContent->QueryInterface(kIDOMNodeIID, (void**)&node); if (NS_SUCCEEDED(res) && node) { - nsIPrivateDOMEvent* pDOMEvent = nsnull; + nsIPrivateDOMEvent* pDOMEvent = nsnull; res = DOMEvent->QueryInterface(kIPrivateDOMEventIID, (void**)&pDOMEvent); if (NS_SUCCEEDED(res) && pDOMEvent) { pDOMEvent->SetTarget(node); - NS_RELEASE(pDOMEvent); + NS_RELEASE(pDOMEvent); // Have the content handle the event. mContent->HandleDOMEvent(*mPresContext, &event, &DOMEvent, NS_EVENT_FLAG_BUBBLE, status); } - NS_RELEASE(node); + NS_RELEASE(node); } NS_RELEASE(DOMEvent); } @@ -1077,10 +1084,11 @@ nsComboboxControlFrame::AddOption(PRInt32 aIndex) { nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); - nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo::GetIID(), + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); - if (NS_SUCCEEDED(rv) && nsnull != listFrame) { - return listFrame->AddOption(aIndex); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->AddOption(aIndex); + NS_RELEASE(listFrame); } return rv; } @@ -1091,10 +1099,11 @@ nsComboboxControlFrame::RemoveOption(PRInt32 aIndex) { nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); - nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo::GetIID(), + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); - if (NS_SUCCEEDED(rv) && nsnull != listFrame) { - return listFrame->RemoveOption(aIndex); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->RemoveOption(aIndex); + NS_RELEASE(listFrame); } return rv; } @@ -1104,10 +1113,25 @@ nsComboboxControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) { nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); - nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo::GetIID(), + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); - if (NS_SUCCEEDED(rv) && nsnull != listFrame) { - return listFrame->SetOptionSelected(aIndex, aValue); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->SetOptionSelected(aIndex, aValue); + NS_RELEASE(listFrame); + } + return rv; +} + +NS_IMETHODIMP +nsComboboxControlFrame::GetOptionSelected(PRInt32 aIndex, PRBool* aValue) +{ + nsISelectControlFrame* listFrame = nsnull; + nsIFrame* dropdownFrame = GetDropdownFrame(); + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), + (void**)&listFrame); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->GetOptionSelected(aIndex, aValue); + NS_RELEASE(listFrame); } return rv; } @@ -1368,4 +1392,42 @@ nsComboboxControlFrame::Blur(nsIDOMEvent* aEvent) return NS_OK; } +//---------------------------------------------------------------------- +// nsIStatefulFrame +// XXX Do we need to implement this here? It is already implemented in +// the ListControlFrame, our child... +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsComboboxControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eSelectType; + return NS_OK; +} +NS_IMETHODIMP +nsComboboxControlFrame::SaveState(nsISupports** aState) +{ + if (!mListControlFrame) return NS_ERROR_UNEXPECTED; + nsIStatefulFrame* sFrame = nsnull; + nsresult res = mListControlFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), + (void**)&sFrame); + if (NS_SUCCEEDED(res) && sFrame) { + res = sFrame->SaveState(aState); + NS_RELEASE(sFrame); + } + return res; +} + +NS_IMETHODIMP +nsComboboxControlFrame::RestoreState(nsISupports* aState) +{ + if (!mListControlFrame) return NS_ERROR_UNEXPECTED; + nsIStatefulFrame* sFrame = nsnull; + nsresult res = mListControlFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), + (void**)&sFrame); + if (NS_SUCCEEDED(res) && sFrame) { + res = sFrame->RestoreState(aState); + NS_RELEASE(sFrame); + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h index a8aed6e33b8..e63a511827b 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h @@ -28,6 +28,7 @@ #include "nsVoidArray.h" #include "nsIAnonymousContentCreator.h" #include "nsISelectControlFrame.h" +#include "nsIStatefulFrame.h" class nsButtonControlFrame; class nsTextControlFrame; @@ -49,8 +50,8 @@ class nsComboboxControlFrame : public nsAreaFrame, public nsIDOMMouseListener, public nsIDOMFocusListener, public nsIAnonymousContentCreator, - public nsISelectControlFrame - + public nsISelectControlFrame, + public nsIStatefulFrame { public: nsComboboxControlFrame(); @@ -140,6 +141,7 @@ public: NS_IMETHOD AddOption(PRInt32 index); NS_IMETHOD RemoveOption(PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); + NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); //nsIDOMEventListener virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); @@ -154,6 +156,11 @@ public: virtual nsresult Focus(nsIDOMEvent* aEvent); virtual nsresult Blur(nsIDOMEvent* aEvent); + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); + protected: // nsHTMLContainerFrame diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index b9db0c8aa0e..c263f53a4e6 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -45,7 +45,9 @@ #include "nsIDOMMouseListener.h" #include "nsIPresShell.h" #include "nsIDOMHTMLInputElement.h" - +#include "nsIStatefulFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID); static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID); @@ -76,11 +78,16 @@ nsFileControlFrame::nsFileControlFrame(): { //Shrink the area around it's contents SetFlags(NS_BLOCK_SHRINK_WRAP); + mCachedState = nsnull; } nsFileControlFrame::~nsFileControlFrame() { NS_IF_RELEASE(mTextContent); + if (mCachedState) { + delete mCachedState; + mCachedState = nsnull; + } } NS_IMETHODIMP @@ -121,25 +128,28 @@ nsFileControlFrame::CreateAnonymousContent(nsISupportsArray& aChildList) return NS_OK; } -nsresult +NS_IMETHODIMP nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) { NS_PRECONDITION(0 != aInstancePtr, "null ptr"); if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { - *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; - NS_ADDREF_THIS(); - return NS_OK; + } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; } else if (aIID.Equals(kIFormControlFrameIID)) { *aInstancePtr = (void*) ((nsIFormControlFrame*) this); return NS_OK; - } else if (aIID.Equals(kIDOMMouseListenerIID)) { - *aInstancePtr = (void*)(nsIDOMMouseListener*) this; - NS_ADDREF_THIS(); - return NS_OK; - } - + } else if (aIID.Equals(kIDOMMouseListenerIID)) { + *aInstancePtr = (void*)(nsIDOMMouseListener*) this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); } @@ -260,6 +270,12 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext, // add ourself as an nsIFormControlFrame nsFormFrame::AddFormControlFrame(aPresContext, *this); mTextFrame = GetTextControlFrame(this); + if (!mTextFrame) return NS_ERROR_UNEXPECTED; + if (mCachedState) { + mTextFrame->SetProperty(nsHTMLAtoms::value, *mCachedState); + delete mCachedState; + mCachedState = nsnull; + } } return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); @@ -291,7 +307,7 @@ nsFileControlFrame::GetTextControlFrame(nsIFrame* aStart) nsIFrame* childFrame = nsnull; aStart->FirstChild(nsnull, &childFrame); - while (nsnull != childFrame) { + while (childFrame) { // see if the child is a text control nsCOMPtr content; childFrame->GetContent(getter_AddRefs(content)); @@ -308,7 +324,7 @@ nsFileControlFrame::GetTextControlFrame(nsIFrame* aStart) // if not continue looking nsTextControlFrame* frame = GetTextControlFrame(childFrame); - if (frame != nsnull) + if (frame) return frame; nsresult rv = childFrame->GetNextSibling(&childFrame); @@ -486,3 +502,50 @@ nsFileControlFrame::Paint(nsIPresContext& aPresContext, { return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsFileControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eFileType; + return NS_OK; +} + +NS_IMETHODIMP +nsFileControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsString* value = nsnull; + nsAutoString string; + nsresult res = mTextFrame->GetProperty(nsHTMLAtoms::value, string); + if (NS_SUCCEEDED(res)) { + char* chars = string.ToNewCString(); + if (chars) { + res = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), (void**)&value); + if (NS_SUCCEEDED(res) && value) { + value->SetData(chars); + } + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + } + *aState = (nsISupports*)value; + return res; +} + +NS_IMETHODIMP +nsFileControlFrame::RestoreState(nsISupports* aState) +{ + char* chars = nsnull; + nsresult res = ((nsISupportsString*)aState)->GetData(&chars); + if (NS_SUCCEEDED(res) && chars) { + // Don't poke mTextFrame, it's not there yet. + mCachedState = new nsString(chars); + if (!mCachedState) res = NS_ERROR_OUT_OF_MEMORY; + nsCRT::free(chars); + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h index a49ab236f33..12efcab41ca 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h @@ -23,6 +23,7 @@ #include "nsIFormControlFrame.h" #include "nsIDOMMouseListener.h" #include "nsIAnonymousContentCreator.h" +#include "nsIStatefulFrame.h" class nsButtonControlFrame; class nsTextControlFrame; @@ -33,7 +34,8 @@ class nsIHTMLContent; class nsFileControlFrame : public nsAreaFrame, public nsIFormControlFrame, public nsIDOMMouseListener, - public nsIAnonymousContentCreator + public nsIAnonymousContentCreator, + public nsIStatefulFrame { public: @@ -144,6 +146,11 @@ public: virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); + protected: nsIWidget* GetWindowTemp(nsIView *aView); // XXX temporary @@ -152,6 +159,7 @@ protected: nsTextControlFrame* mTextFrame; nsFormFrame* mFormFrame; nsIHTMLContent* mTextContent; + nsString* mCachedState; private: nsTextControlFrame* GetTextControlFrame(nsIFrame* aStart); diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index 97caa4a8d30..2071d269a68 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -37,10 +37,13 @@ #include "nsIReflowCommand.h" #include "nsIPresShell.h" #include "nsHTMLParts.h" - #include "nsIDOMEventReceiver.h" #include "nsIEventStateManager.h" #include "nsIDOMUIEvent.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsArray.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID); static NS_DEFINE_IID(kIDOMMouseMotionListenerIID, NS_IDOMMOUSEMOTIONLISTENER_IID); @@ -150,6 +153,11 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_ADDREF_THIS(); return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } return nsScrollFrame::QueryInterface(aIID, aInstancePtr); } @@ -1637,6 +1645,15 @@ nsListControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) return NS_OK; } +//--------------------------------------------------------- +// Determine if the specified item in the listbox is selected. +NS_IMETHODIMP +nsListControlFrame::GetOptionSelected(PRInt32 aIndex, PRBool* aValue) +{ + *aValue = IsContentSelectedByIndex(aIndex); + return NS_OK; +} + //---------------------------------------------------------------------- // End nsISelectControlFrame //---------------------------------------------------------------------- @@ -2150,3 +2167,78 @@ nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) return NS_OK; } +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsListControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eSelectType; + return NS_OK; +} + +NS_IMETHODIMP +nsListControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsArray* value = nsnull; + nsresult res = NS_NewISupportsArray(&value); + if (NS_SUCCEEDED(res) && value) { + PRInt32 j=0; + PRInt32 length = 0; + GetNumberOfOptions(&length); + PRInt32 i; + for (i=0; iSetData(i); + if (NS_SUCCEEDED(res)) { + PRBool okay = value->InsertElementAt((nsISupports *)thisVal, j++); + if (!okay) res = NS_ERROR_OUT_OF_MEMORY; // Most likely cause; + } + if (!NS_SUCCEEDED(res)) NS_RELEASE(thisVal); + } + } + if (!NS_SUCCEEDED(res)) break; + } + if (iCount(&count); + if (NS_SUCCEEDED(res)) { + nsISupportsPRInt32* thisVal = nsnull; + PRInt32 j=0; + for (PRUint32 i=0; iElementAt(i); + if (thisVal) { + res = thisVal->GetData(&j); + if (NS_SUCCEEDED(res)) { + res = SetOptionSelected(j, PR_TRUE); + } + } else { + res = NS_ERROR_UNEXPECTED; + } + if (!NS_SUCCEEDED(res)) break; + } + } + } + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.h b/mozilla/layout/html/forms/src/nsListControlFrame.h index fccf099fe46..24581a604c7 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.h +++ b/mozilla/layout/html/forms/src/nsListControlFrame.h @@ -26,6 +26,7 @@ #include "nsIDOMMouseListener.h" #include "nsIDOMMouseMotionListener.h" #include "nsIDOMKeyListener.h" +#include "nsIStatefulFrame.h" class nsIDOMHTMLSelectElement; class nsIDOMHTMLCollection; @@ -44,7 +45,8 @@ class nsListControlFrame : public nsScrollFrame, public nsIDOMMouseListener, public nsIDOMMouseMotionListener, public nsIDOMKeyListener, - public nsISelectControlFrame + public nsISelectControlFrame, + public nsIStatefulFrame { public: friend nsresult NS_NewListControlFrame(nsIFrame** aNewFrame); @@ -120,6 +122,12 @@ public: NS_IMETHOD AddOption(PRInt32 index); NS_IMETHOD RemoveOption(PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); + NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); //nsIDOMEventListener virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); diff --git a/mozilla/layout/html/forms/src/nsNativeFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsNativeFormControlFrame.cpp index 0596dfb5039..90a4db40b36 100644 --- a/mozilla/layout/html/forms/src/nsNativeFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsNativeFormControlFrame.cpp @@ -53,7 +53,7 @@ nsNativeFormControlFrame::Reflow(nsIPresContext& aPresContext, nsReflowStatus& aStatus) { if (mDidInit) { - return Inherited::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + return nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); } nsresult result = NS_OK; @@ -264,7 +264,7 @@ NS_METHOD nsNativeFormControlFrame::HandleEvent(nsIPresContext& aPresContext, nsEventStatus& aEventStatus) { if (nsnull == mWidget) { - return Inherited::HandleEvent(aPresContext, aEvent, aEventStatus); + return nsFormControlFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } if (nsEventStatus_eConsumeNoDefault == aEventStatus) { @@ -298,11 +298,7 @@ NS_METHOD nsNativeFormControlFrame::HandleEvent(nsIPresContext& aPresContext, break; case NS_MOUSE_LEFT_BUTTON_DOWN: - if (NS_FORM_INPUT_IMAGE == type) { - mLastMouseState = eMouseDown; - } else { - mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; - } + mLastMouseState = eMouseDown; break; case NS_MOUSE_LEFT_BUTTON_UP: @@ -321,7 +317,7 @@ NS_METHOD nsNativeFormControlFrame::HandleEvent(nsIPresContext& aPresContext, break; case NS_KEY_DOWN: - return Inherited::HandleEvent(aPresContext, aEvent, aEventStatus); + return nsFormControlFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } aEventStatus = nsEventStatus_eConsumeDoDefault; diff --git a/mozilla/layout/html/forms/src/nsNativeFormControlFrame.h b/mozilla/layout/html/forms/src/nsNativeFormControlFrame.h index 8b75cbe7998..eb8b1c72386 100644 --- a/mozilla/layout/html/forms/src/nsNativeFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsNativeFormControlFrame.h @@ -29,9 +29,6 @@ */ class nsNativeFormControlFrame : public nsFormControlFrame { -private: - typedef nsFormControlFrame Inherited; - public: nsNativeFormControlFrame(); diff --git a/mozilla/layout/html/forms/src/nsNativeSelectControlFrame.cpp b/mozilla/layout/html/forms/src/nsNativeSelectControlFrame.cpp index 5758a9c29d8..18692f4f482 100644 --- a/mozilla/layout/html/forms/src/nsNativeSelectControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsNativeSelectControlFrame.cpp @@ -50,6 +50,10 @@ #include "nsILookAndFeel.h" #include "nsIComponentManager.h" #include "nsISelectControlFrame.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsArray.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID); static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID); @@ -63,16 +67,13 @@ static NS_DEFINE_IID(kListCID, NS_LISTBOX_CID); static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID); static NS_DEFINE_IID(kISelectControlFrameIID, NS_ISELECTCONTROLFRAME_IID); - class nsOption; class nsNativeSelectControlFrame : public nsNativeFormControlFrame, - public nsISelectControlFrame + public nsISelectControlFrame, + public nsIStatefulFrame { -private: - typedef nsNativeFormControlFrame Inherited; - public: nsNativeSelectControlFrame(); @@ -149,6 +150,12 @@ public: NS_IMETHOD AddOption(PRInt32 aIndex); NS_IMETHOD RemoveOption(PRInt32 aIndex); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); + NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); protected: PRInt32 mNumRows; @@ -159,6 +166,7 @@ protected: PRBool GetOptionValue(nsIDOMHTMLCollection& aCollecton, PRUint32 aIndex, nsString& aValue); PRInt32 GetSelectedIndex(); nsresult UpdateWidgetToCache(PRBool aDeselectFirst = PR_TRUE); + nsresult Deselect(); virtual void GetDesiredSize(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, @@ -174,6 +182,7 @@ protected: // GFX-rendered or not. This is used to detect changes in MouseClicked PRInt32 mNumOptions; PRBool* mOptionSelected; + PRBool mCachedState; // A flag meaning "Don't reset state on PostCreateWidget" // Accessor methods for mOptionsSelected and mNumOptions void GetOptionSelectedCache(PRInt32 index, PRBool* aValue); @@ -214,6 +223,7 @@ nsNativeSelectControlFrame::nsNativeSelectControlFrame() mNumRows = 0; mNumOptions = 0; mOptionSelected = nsnull; + mCachedState = PR_FALSE; } // XXX is this the right way to clean up? @@ -229,12 +239,17 @@ nsNativeSelectControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePt NS_PRECONDITION(0 != aInstancePtr, "null ptr"); if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kISelectControlFrameIID)) { - *aInstancePtr = (void*) ((nsISelectControlFrame*) this); + } else if (aIID.Equals(NS_GET_IID(nsISelectControlFrame))) { + *aInstancePtr = (void*)(nsISelectControlFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); return NS_OK; } - return Inherited::QueryInterface(aIID, aInstancePtr); + + return nsNativeFormControlFrame::QueryInterface(aIID, aInstancePtr); } nscoord @@ -748,21 +763,26 @@ nsNativeSelectControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumV void nsNativeSelectControlFrame::Reset() { - // Reset selection to default - nsIDOMHTMLCollection* options = GetOptions(); - if (!options) return; // XXX NS_ERROR_UNEXPECTED; - PRUint32 numOptions; - options->GetLength(&numOptions); - for (PRUint32 i = 0; i < numOptions; i++) { - nsIDOMHTMLOptionElement* option = GetOption(*options, i); - if (option) { - // Cache the state of each option locally - PRBool selected = PR_FALSE; - option->GetDefaultSelected(&selected); - SetOptionSelectedCache(i, selected); + if (mCachedState) { + mCachedState = PR_FALSE; + } else { + // Reset selection to default + nsIDOMHTMLCollection* options = GetOptions(); + if (!options) return; // XXX NS_ERROR_UNEXPECTED; + PRUint32 numOptions; + options->GetLength(&numOptions); + for (PRUint32 i = 0; i < numOptions; i++) { + nsIDOMHTMLOptionElement* option = GetOption(*options, i); + if (option) { + // Cache the state of each option locally + PRBool selected = PR_FALSE; + option->GetDefaultSelected(&selected); + SetOptionSelectedCache(i, selected); + NS_RELEASE(option); + } } + NS_RELEASE(options); } - NS_RELEASE(options); UpdateWidgetToCache(); } @@ -1029,7 +1049,7 @@ nsNativeSelectControlFrame::Paint(nsIPresContext& aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, + nsNativeFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { PaintSelectControl(aPresContext, aRenderingContext, aDirtyRect); @@ -1193,7 +1213,7 @@ void nsNativeSelectControlFrame::GetOptionSelectedWidget(PRInt32 indx, PRBool* a void nsNativeSelectControlFrame::SetOptionSelectedCache(PRInt32 indx, PRBool aValue) { if (nsnull != mOptionSelected) { - if (mNumOptions >= indx) { + if ((-1 < indx) && (mNumOptions >= indx)) { mOptionSelected[indx] = aValue; } } @@ -1225,14 +1245,15 @@ NS_IMETHODIMP nsNativeSelectControlFrame::SetProperty(nsIAtom* aName, const nsSt return NS_ERROR_INVALID_ARG; // Couldn't convert to integer // Update local cache of selected values - for (PRInt32 i=0; i < mNumOptions; i++) // Deselect all options - SetOptionSelectedCache(i, PR_FALSE); - SetOptionSelectedCache(selectedIndex, PR_TRUE); // Select selectedIndex + nsresult res = Deselect(); + if (NS_SUCCEEDED(res)) { + SetOptionSelectedCache(selectedIndex, PR_TRUE); // Select selectedIndex + } // Update widget UpdateWidgetToCache(); } else { - return Inherited::SetProperty(aName, aValue); + return nsNativeFormControlFrame::SetProperty(aName, aValue); } return NS_OK; } @@ -1267,7 +1288,12 @@ NS_IMETHODIMP nsNativeSelectControlFrame::AddOption(PRInt32 aIndex) // Get the correct selected value and text of the option nsIDOMHTMLOptionElement* option = GetOption(*options, i); - option->GetDefaultSelected(&selected); + if (option) { + option->GetDefaultSelected(&selected); + NS_RELEASE(option); + } else { + selected = PR_FALSE; // XXX failure case. + } mOptionSelected[j]=selected; j++; } @@ -1342,7 +1368,12 @@ NS_IMETHODIMP nsNativeSelectControlFrame::RemoveOption(PRInt32 aIndex) // Get the default (XXXincorrect) selected value and text of the option nsIDOMHTMLOptionElement* option = GetOption(*options, i); - option->GetDefaultSelected(&selected); // Should be sel, not defsel :( + if (option) { + option->GetDefaultSelected(&selected); // Should be sel, not defsel :( + NS_RELEASE(option); + } else { + selected = PR_FALSE; // XXX failure case + } mOptionSelected[i]=selected; } } @@ -1364,43 +1395,43 @@ NS_IMETHODIMP nsNativeSelectControlFrame::GetProperty(nsIAtom* aName, nsString& PRInt32 error = 0; PRBool selected = PR_FALSE; PRInt32 indx = aValue.ToInteger(&error, 10); // Get index from aValue -// if (error == 0) -// GetOptionSelectedWidget(indx, &selected); GetOptionSelectedCache(indx, &selected); nsFormControlHelper::GetBoolString(selected, aValue); // For selectedIndex, get the value from the widget } else if (nsHTMLAtoms::selectedindex == aName) { PRInt32 selectedIndex = -1; - PRBool multiple; - GetMultiple(&multiple); - if (!multiple) { - nsIListWidget* listWidget; - nsresult result = mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget); - if ((NS_OK == result) && (nsnull != listWidget)) { - selectedIndex = listWidget->GetSelectedIndex(); - NS_RELEASE(listWidget); - } - } else { - // Listboxes don't do GetSelectedIndex on windows. Use GetSelectedIndices - nsIListBox* listBox; - nsresult result = mWidget->QueryInterface(kListBoxIID, (void **) &listBox); - if ((NS_OK == result) && (nsnull != listBox)) { - PRUint32 numSelected = listBox->GetSelectedCount(); - PRInt32* selOptions = nsnull; - if (numSelected > 0) { - // Could we set numSelected to 1 here? (memory, speed optimization) - selOptions = new PRInt32[numSelected]; - listBox->GetSelectedIndices(selOptions, numSelected); - selectedIndex = selOptions[0]; - delete[] selOptions; + if (mWidget) { + PRBool multiple; + GetMultiple(&multiple); + if (!multiple) { + nsIListWidget* listWidget; + nsresult result = mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget); + if ((NS_OK == result) && (nsnull != listWidget)) { + selectedIndex = listWidget->GetSelectedIndex(); + NS_RELEASE(listWidget); + } + } else { + // Listboxes don't do GetSelectedIndex on windows. Use GetSelectedIndices + nsIListBox* listBox; + nsresult result = mWidget->QueryInterface(kListBoxIID, (void **) &listBox); + if ((NS_OK == result) && (nsnull != listBox)) { + PRUint32 numSelected = listBox->GetSelectedCount(); + PRInt32* selOptions = nsnull; + if (numSelected > 0) { + // Could we set numSelected to 1 here? (memory, speed optimization) + selOptions = new PRInt32[numSelected]; + listBox->GetSelectedIndices(selOptions, numSelected); + selectedIndex = selOptions[0]; + delete[] selOptions; + } + NS_RELEASE(listBox); } - NS_RELEASE(listBox); } } aValue.Append(selectedIndex, 10); } else { - return Inherited::GetProperty(aName, aValue); + return nsNativeFormControlFrame::GetProperty(aName, aValue); } return NS_OK; } @@ -1409,8 +1440,6 @@ NS_IMETHODIMP nsNativeSelectControlFrame::GetProperty(nsIAtom* aName, nsString& NS_IMETHODIMP nsNativeSelectControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) { - // Get Selected index out of Content model - PRInt32 selectedIndex = GetSelectedIndex(); PRBool multiple = PR_FALSE; GetMultiple(&multiple); @@ -1418,18 +1447,38 @@ nsNativeSelectControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) SetOptionSelectedCache(aIndex, aValue); } else { if (aValue) { - SetOptionSelectedCache(selectedIndex, PR_FALSE); + // Get Selected index out of Content model + PRInt32 selectedIndex = GetSelectedIndex(); + if (-1 < selectedIndex) + SetOptionSelectedCache(selectedIndex, PR_FALSE); SetOptionSelectedCache(aIndex, PR_TRUE); } else { SetOptionSelectedCache(aIndex, PR_FALSE); } } - return UpdateWidgetToCache(!aValue); // Don't deselect all if adding selection + // Note that UpdateWidgetToCache may return NS_ERROR_UNEXPECTED if the + // widget is not created yet. We can safely ignore this as when Reset is + // called, it will update the widget to the cache's state. + UpdateWidgetToCache(!aValue); // Don't deselect all if adding selection + return NS_OK; +} + +NS_IMETHODIMP +nsNativeSelectControlFrame::GetOptionSelected(PRInt32 aIndex, PRBool* aValue) +{ + // Determine if option is selected in local cache + GetOptionSelectedCache(aIndex, aValue); + return NS_OK; } nsresult nsNativeSelectControlFrame::UpdateWidgetToCache(PRBool aDeselectFirst) { + if (!mWidget) { + mCachedState = PR_TRUE; // Handle this update later when widget is created. + return NS_OK; + } + // Grab the list widget nsIListWidget* listWidget; nsresult result = mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget); @@ -1469,3 +1518,86 @@ nsNativeSelectControlFrame::AppendFrames(nsIPresContext& aPresContext, //NS_PRECONDITION(PR_FALSE, "not a container"); return NS_ERROR_UNEXPECTED; } + +nsresult +nsNativeSelectControlFrame::Deselect() +{ + nsresult res = NS_OK; + for (PRInt32 i=0; (iSetData(i); + if (NS_SUCCEEDED(res)) { + PRBool okay = value->InsertElementAt((nsISupports *)thisVal, j++); + if (!okay) res = NS_ERROR_OUT_OF_MEMORY; // Most likely cause; + } + if (!NS_SUCCEEDED(res)) NS_RELEASE(thisVal); + } + } + if (!NS_SUCCEEDED(res)) break; + } + if (iCount(&count); + if (NS_SUCCEEDED(res)) { + nsISupportsPRInt32* thisVal = nsnull; + PRInt32 j=0; + for (PRUint32 k=0; kElementAt(k); + if (thisVal) { + res = thisVal->GetData(&j); + if (NS_SUCCEEDED(res)) { + res = SetOptionSelected(j, PR_TRUE); + } + } else { + res = NS_ERROR_UNEXPECTED; + } + if (!NS_SUCCEEDED(res)) break; + } + } + } + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsNativeTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsNativeTextControlFrame.cpp index b7f48171a23..a1d2a50010b 100644 --- a/mozilla/layout/html/forms/src/nsNativeTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsNativeTextControlFrame.cpp @@ -71,6 +71,19 @@ NS_NewNativeTextControlFrame(nsIFrame** aNewFrame) return NS_OK; } +nsNativeTextControlFrame::nsNativeTextControlFrame() +: mCachedState(nsnull) +{ +} + +nsNativeTextControlFrame::~nsNativeTextControlFrame() +{ + if (mCachedState) { + delete mCachedState; + mCachedState = nsnull; + } +} + void nsNativeTextControlFrame::EnterPressed(nsIPresContext& aPresContext) { @@ -177,7 +190,7 @@ nsNativeTextControlFrame::AttributeChanged(nsIPresContext* aPresContext, // Allow the base class to handle common attributes supported // by all form elements... else { - result = Inherited::AttributeChanged(aPresContext, aChild, aAttribute, aHint); + result = nsNativeFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint); } NS_RELEASE(text); } @@ -208,12 +221,12 @@ nsNativeTextControlFrame::AttributeChanged(nsIPresContext* aPresContext, // Allow the base class to handle common attributes supported // by all form elements... else { - result = Inherited::AttributeChanged(aPresContext, aChild, aAttribute, aHint); + result = nsNativeFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint); } NS_RELEASE(textArea); } else { // We didn't get a Text or TextArea. Uh oh... - result = Inherited::AttributeChanged(aPresContext, aChild, aAttribute, aHint); + result = nsNativeFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint); } } } @@ -244,7 +257,12 @@ nsNativeTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nsITextAreaWidget* textArea = nsnull; nsITextWidget* text = nsnull; if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) { - GetText(&value, PR_TRUE); + if (mCachedState) { + value = *mCachedState; + delete mCachedState; + mCachedState = nsnull; + } else + GetText(&value, PR_TRUE); text->SetText(value, ignore); PRInt32 maxLength; nsresult result = GetMaxLength(&maxLength); @@ -253,7 +271,12 @@ nsNativeTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext, } NS_RELEASE(text); } else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) { - GetText(&value, PR_TRUE); + if (mCachedState) { + value = *mCachedState; + delete mCachedState; + mCachedState = nsnull; + } else + GetText(&value, PR_TRUE); textArea->SetText(value, ignore); NS_RELEASE(textArea); } @@ -333,7 +356,7 @@ nsNativeTextControlFrame::PaintTextControlBackground(nsIPresContext& aPresContex nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + nsNativeFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } void @@ -539,7 +562,9 @@ void nsNativeTextControlFrame::SetTextControlFrameState(const nsString& aValue) textArea->SetText(aValue,size); NS_RELEASE(textArea); } - } + } else { + mCachedState = new nsString(aValue); + } } NS_IMETHODIMP nsNativeTextControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue) @@ -565,7 +590,7 @@ NS_IMETHODIMP nsNativeTextControlFrame::SetProperty(nsIAtom* aName, const nsStri } } else { - return Inherited::SetProperty(aName, aValue); + return nsNativeFormControlFrame::SetProperty(aName, aValue); } return rv; } @@ -579,7 +604,7 @@ NS_IMETHODIMP nsNativeTextControlFrame::GetProperty(nsIAtom* aName, nsString& aV GetTextControlFrameState(aValue); } else { - return Inherited::GetProperty(aName, aValue); + return nsNativeFormControlFrame::GetProperty(aName, aValue); } return NS_OK; diff --git a/mozilla/layout/html/forms/src/nsNativeTextControlFrame.h b/mozilla/layout/html/forms/src/nsNativeTextControlFrame.h index d999b1b8b2d..f262dfa9ac1 100644 --- a/mozilla/layout/html/forms/src/nsNativeTextControlFrame.h +++ b/mozilla/layout/html/forms/src/nsNativeTextControlFrame.h @@ -26,11 +26,11 @@ class nsIPresContext; class nsNativeTextControlFrame : public nsTextControlFrame { -private: - typedef nsNativeFormControlFrame Inherited; - public: - // nsIFormControlFrame + nsNativeTextControlFrame(); + virtual ~nsNativeTextControlFrame(); + + // nsIFormControlFrame NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue); NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); @@ -75,6 +75,8 @@ public: virtual nsresult RequiresWidget(PRBool &aRequiresWidget); +protected: + nsString* mCachedState; }; #endif diff --git a/mozilla/layout/html/forms/src/nsRadioControlFrame.cpp b/mozilla/layout/html/forms/src/nsRadioControlFrame.cpp index 10019e78a86..17dae2e5170 100644 --- a/mozilla/layout/html/forms/src/nsRadioControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsRadioControlFrame.cpp @@ -25,11 +25,12 @@ #include "nsFormFrame.h" #include "nsINameSpaceManager.h" #include "nsFormFrame.h" - +#include "nsIStatefulFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIRadioControlFrameIID, NS_IRADIOCONTROLFRAME_IID); - nsresult nsRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) { @@ -41,8 +42,13 @@ nsRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) *aInstancePtr = (void*) ((nsIRadioControlFrame*) this); return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*) ((nsIStatefulFrame*) this); + NS_ADDREF_THIS(); + return NS_OK; + } - return Inherited::QueryInterface(aIID, aInstancePtr); + return nsNativeFormControlFrame::QueryInterface(aIID, aInstancePtr); } @@ -199,7 +205,7 @@ nsRadioControlFrame::HandleEvent(nsIPresContext& aPresContext, break; } - return(Inherited::HandleEvent(aPresContext, aEvent, aEventStatus)); + return(nsNativeFormControlFrame::HandleEvent(aPresContext, aEvent, aEventStatus)); } void nsRadioControlFrame::GetRadioControlFrameState(nsString& aValue) @@ -225,7 +231,7 @@ NS_IMETHODIMP nsRadioControlFrame::SetProperty(nsIAtom* aName, const nsString& a } } else { - return Inherited::SetProperty(aName, aValue); + return nsNativeFormControlFrame::SetProperty(aName, aValue); } return NS_OK; @@ -240,7 +246,7 @@ NS_IMETHODIMP nsRadioControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) GetRadioControlFrameState(aValue); } else { - return Inherited::GetProperty(aName, aValue); + return nsNativeFormControlFrame::GetProperty(aName, aValue); } return NS_OK; @@ -252,3 +258,48 @@ nsresult nsRadioControlFrame::RequiresWidget(PRBool& aRequiresWidget) aRequiresWidget = PR_FALSE; return NS_OK; } + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsRadioControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eRadioType; + return NS_OK; +} + +NS_IMETHODIMP +nsRadioControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsString* value = nsnull; + nsresult res = NS_OK; + nsAutoString string; + GetRadioControlFrameState(string); + char* chars = string.ToNewCString(); + if (chars) { + res = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), (void**)&value); + if (NS_SUCCEEDED(res) && value) { + value->SetData(chars); + } + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + *aState = (nsISupports*)value; + return NS_OK; +} + +NS_IMETHODIMP +nsRadioControlFrame::RestoreState(nsISupports* aState) +{ + char* chars = nsnull; + nsresult res = ((nsISupportsString*)aState)->GetData(&chars); + if (NS_SUCCEEDED(res) && chars) { + nsAutoString string(chars); + SetRadioControlFrameState(string); + nsCRT::free(chars); + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsRadioControlFrame.h b/mozilla/layout/html/forms/src/nsRadioControlFrame.h index 9851b07fef2..4f0c4610cdc 100644 --- a/mozilla/layout/html/forms/src/nsRadioControlFrame.h +++ b/mozilla/layout/html/forms/src/nsRadioControlFrame.h @@ -23,15 +23,15 @@ #include "nsNativeFormControlFrame.h" #include "nsVoidArray.h" #include "nsString.h" +#include "nsIStatefulFrame.h" class nsIAtom; // nsRadioControlFrame -class nsRadioControlFrame : public nsNativeFormControlFrame, public nsIRadioControlFrame +class nsRadioControlFrame : public nsNativeFormControlFrame, + public nsIRadioControlFrame, + public nsIStatefulFrame { -private: - typedef nsNativeFormControlFrame Inherited; - public: // nsFormControlFrame overrides nsresult RequiresWidget(PRBool &aHasWidget); @@ -71,13 +71,17 @@ public: // Expect this code to repackaged and moved to a new location in the future. // - NS_IMETHOD HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus); ///XXX: End o the temporary methods + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); + protected: // Utility methods for implementing SetProperty/GetProperty diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp index 8bd0417bb75..8ec3a4ca4c1 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp @@ -45,6 +45,9 @@ #include "nsIFontMetrics.h" #include "nsILookAndFeel.h" #include "nsIComponentManager.h" +#include "nsIStatefulFrame.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID); @@ -67,6 +70,21 @@ nsTextControlFrame::~nsTextControlFrame() { } +nsresult +nsTextControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_PRECONDITION(0 != aInstancePtr, "null ptr"); + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} + nscoord nsTextControlFrame::GetVerticalBorderWidth(float aPixToTwip) const { @@ -355,3 +373,49 @@ nsTextControlFrame::GetWrapProperty(nsString &aOutValue) } return result; } + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsTextControlFrame::GetStateType(nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eTextType; + return NS_OK; +} + +NS_IMETHODIMP +nsTextControlFrame::SaveState(nsISupports** aState) +{ + nsISupportsString* value = nsnull; + nsAutoString string; + nsresult res = GetProperty(nsHTMLAtoms::value, string); + if (NS_SUCCEEDED(res)) { + char* chars = string.ToNewCString(); + if (chars) { + res = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), (void**)&value); + if (NS_SUCCEEDED(res) && value) { + value->SetData(chars); + } + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + } + *aState = (nsISupports*)value; + return res; +} + +NS_IMETHODIMP +nsTextControlFrame::RestoreState(nsISupports* aState) +{ + char* chars = nsnull; + nsresult res = ((nsISupportsString*)aState)->GetData(&chars); + if (NS_SUCCEEDED(res) && chars) { + nsAutoString string(chars); + res = SetProperty(nsHTMLAtoms::value, string); + nsCRT::free(chars); + } + return res; +} diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.h b/mozilla/layout/html/forms/src/nsTextControlFrame.h index 953ef90653e..9395d485755 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.h +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.h @@ -20,11 +20,14 @@ #define nsTextControlFrame_h___ #include "nsNativeFormControlFrame.h" +#include "nsIStatefulFrame.h" + class nsIContent; class nsIFrame; class nsIPresContext; -class nsTextControlFrame : public nsNativeFormControlFrame +class nsTextControlFrame : public nsNativeFormControlFrame, + public nsIStatefulFrame { /* ---------- methods implemented by base class ---------- */ public: @@ -34,6 +37,8 @@ public: virtual const nsIID& GetCID(); virtual const nsIID& GetIID(); + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD GetFrameName(nsString& aResult) const; virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const; @@ -53,6 +58,11 @@ public: * returns NS_CONTENT_ATTR_NOT_THERE if the property does not exist for this */ NS_IMETHOD GetWrapProperty(nsString &aOutValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(StateType* aStateType); + NS_IMETHOD SaveState(nsISupports** aState); + NS_IMETHOD RestoreState(nsISupports* aState); protected: @@ -67,6 +77,9 @@ protected: PRInt32 GetDefaultColumnWidth() const { return (PRInt32)(20); } // this was DEFAULT_PIXEL_WIDTH +private: + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } /* ---------- abstract methods derived class must implement ---------- */