the printing of headers and footers. Printing of selection is implemented by the frames figuring out if they are in the selection and painting if they or not they they don't paint. This also only allows the printing of the first page of selections, alothough it is well documented where this is implemeted so it can be removed. Bugs 63426, 31218, 61075 r=dcone,kmcclusk,erik,buster sr=waterson git-svn-id: svn://10.0.0.236/trunk@85624 18797224-902f-48f8-a5cc-f745e15eee43
424 lines
13 KiB
C++
424 lines
13 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
#include "nsGfxRadioControlFrame.h"
|
|
#include "nsHTMLAtoms.h"
|
|
#include "nsHTMLParts.h"
|
|
#include "nsFormFrame.h"
|
|
#include "nsIFormControl.h"
|
|
#include "nsIContent.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsIComponentManager.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsCSSRendering.h"
|
|
#include "nsIPresState.h"
|
|
#include "nsINameSpaceManager.h"
|
|
|
|
|
|
nsresult
|
|
NS_NewGfxRadioControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|
{
|
|
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
|
if (nsnull == aNewFrame) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
nsGfxRadioControlFrame* it = new (aPresShell) nsGfxRadioControlFrame;
|
|
if (!it) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
*aNewFrame = it;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsGfxRadioControlFrame::nsGfxRadioControlFrame()
|
|
{
|
|
// Initialize GFX-rendered state
|
|
mChecked = PR_FALSE;
|
|
mRadioButtonFaceStyle = nsnull;
|
|
}
|
|
|
|
nsGfxRadioControlFrame::~nsGfxRadioControlFrame()
|
|
{
|
|
NS_IF_RELEASE(mRadioButtonFaceStyle);
|
|
}
|
|
|
|
// Frames are not refcounted, no need to AddRef
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|
{
|
|
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
|
|
if (NULL == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (aIID.Equals(NS_GET_IID(nsIRadioControlFrame))) {
|
|
*aInstancePtr = (void*) ((nsIRadioControlFrame*) this);
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
|
|
*aInstancePtr = (void*) ((nsIStatefulFrame*) this);
|
|
return NS_OK;
|
|
}
|
|
|
|
return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex,
|
|
nsIStyleContext** aStyleContext) const
|
|
{
|
|
NS_PRECONDITION(nsnull != aStyleContext, "null OUT parameter pointer");
|
|
if (aIndex < 0) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
*aStyleContext = nsnull;
|
|
switch (aIndex) {
|
|
case NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX:
|
|
*aStyleContext = mRadioButtonFaceStyle;
|
|
NS_IF_ADDREF(*aStyleContext);
|
|
break;
|
|
default:
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
|
|
nsIStyleContext* aStyleContext)
|
|
{
|
|
if (aIndex < 0) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
switch (aIndex) {
|
|
case NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX:
|
|
NS_IF_RELEASE(mRadioButtonFaceStyle);
|
|
mRadioButtonFaceStyle = aStyleContext;
|
|
NS_IF_ADDREF(aStyleContext);
|
|
break;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsAReadableString& aValue)
|
|
{
|
|
if (nsHTMLAtoms::checked == aName) {
|
|
PRBool state = (aValue.Equals(NS_STRING_TRUE)) ? PR_TRUE : PR_FALSE;
|
|
|
|
|
|
// if there is no form than the radiobtn is an orphan
|
|
if (mFormFrame) {
|
|
// if this failed then it didn't have a named radio group
|
|
if (NS_FAILED(mFormFrame->OnRadioChecked(aPresContext, *this, state))) {
|
|
// The line below is commented out to duplicate NavQuirks behavior
|
|
//SetRadioState(aPresContext, state);
|
|
}
|
|
} else {
|
|
SetRadioState(aPresContext, state);
|
|
}
|
|
}
|
|
else {
|
|
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
NS_IMETHODIMP nsGfxRadioControlFrame::GetProperty(nsIAtom* aName, nsAWritableString& aValue)
|
|
{
|
|
// Return the value of the property from the widget it is not null.
|
|
// If is null, assume the widget is GFX-rendered and return a member variable instead.
|
|
|
|
if (nsHTMLAtoms::checked == aName) {
|
|
nsFormControlHelper::GetBoolString(GetRadioState(), aValue);
|
|
} else {
|
|
return nsFormControlFrame::GetProperty(aName, aValue);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
PRBool
|
|
nsGfxRadioControlFrame::GetChecked()
|
|
{
|
|
PRBool checked = PR_FALSE;
|
|
GetCurrentCheckState(&checked);
|
|
return(checked);
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
PRBool
|
|
nsGfxRadioControlFrame::GetDefaultChecked()
|
|
{
|
|
PRBool checked = PR_FALSE;
|
|
GetDefaultCheckState(&checked);
|
|
return(checked);
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void
|
|
nsGfxRadioControlFrame::SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue)
|
|
{
|
|
if (aSetInitialValue) {
|
|
if (aValue) {
|
|
mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, NS_ConvertASCIItoUCS2("1"), PR_FALSE); // XXX should be "empty" value
|
|
} else {
|
|
mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, NS_ConvertASCIItoUCS2("0"), PR_FALSE);
|
|
}
|
|
}
|
|
|
|
SetRadioState(aPresContext, aValue);
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext)
|
|
{
|
|
mRadioButtonFaceStyle = aRadioButtonFaceStyleContext;
|
|
NS_ADDREF(mRadioButtonFaceStyle);
|
|
return NS_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::GetRadioGroupSelectedContent(nsIContent ** aRadioBtn)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aRadioBtn);
|
|
nsFormFrame::GetRadioGroupSelectedContent(this, aRadioBtn);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
PRBool
|
|
nsGfxRadioControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
|
|
nsString* aValues, nsString* aNames)
|
|
{
|
|
nsAutoString name;
|
|
nsresult result = GetName(&name);
|
|
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
|
|
return PR_FALSE;
|
|
}
|
|
|
|
PRBool state = GetRadioState();
|
|
|
|
if(PR_TRUE != state) {
|
|
return PR_FALSE;
|
|
}
|
|
|
|
nsAutoString value;
|
|
result = GetValue(&value);
|
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
|
|
aValues[0] = value;
|
|
} else {
|
|
aValues[0].AssignWithConversion("on");
|
|
}
|
|
aNames[0] = name;
|
|
aNumValues = 1;
|
|
|
|
return PR_TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void
|
|
nsGfxRadioControlFrame::Reset(nsIPresContext* aPresContext)
|
|
{
|
|
PRBool checked = PR_TRUE;
|
|
GetDefaultCheckState(&checked);
|
|
SetCurrentCheckState(checked);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::HandleEvent(nsIPresContext* aPresContext,
|
|
nsGUIEvent* aEvent,
|
|
nsEventStatus* aEventStatus)
|
|
{
|
|
// Check for user-input:none style
|
|
const nsStyleUserInterface* uiStyle;
|
|
GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct *&)uiStyle);
|
|
if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE || uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED)
|
|
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
|
|
|
// otherwise, do nothing. Events are handled by the DOM.
|
|
return NS_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void
|
|
nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext,
|
|
nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect)
|
|
{
|
|
|
|
PRBool checked = PR_TRUE;
|
|
GetCurrentCheckState(&checked); // Get check state from the content model
|
|
if (PR_TRUE == checked) {
|
|
// Paint the button for the radio button using CSS background rendering code
|
|
if (nsnull != mRadioButtonFaceStyle) {
|
|
const nsStyleColor* myColor = (const nsStyleColor*)
|
|
mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Color);
|
|
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
|
|
mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Spacing);
|
|
const nsStylePosition* myPosition = (const nsStylePosition*)
|
|
mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Position);
|
|
|
|
nscoord width = myPosition->mWidth.GetCoordValue();
|
|
nscoord height = myPosition->mHeight.GetCoordValue();
|
|
// Position the button centered within the radio control's rectangle.
|
|
nscoord x = (mRect.width - width) / 2;
|
|
nscoord y = (mRect.height - height) / 2;
|
|
nsRect rect(x, y, width, height);
|
|
|
|
// So we will use the PaintBackground to paint the dot,
|
|
// but it uses the mBackgroundColor for painting and we need to use the mColor
|
|
// so create a temporary style color struct and set it up appropriately
|
|
nsStyleColor tmpColor = *myColor;
|
|
tmpColor.mBackgroundColor = myColor->mColor;
|
|
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
|
|
aDirtyRect, rect, tmpColor, *mySpacing, 0, 0);
|
|
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
|
|
aDirtyRect, rect, *mySpacing, mRadioButtonFaceStyle, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
NS_METHOD
|
|
nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
|
|
nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect,
|
|
nsFramePaintLayer aWhichLayer)
|
|
{
|
|
PRBool isVisible;
|
|
if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
|
|
return NS_OK;
|
|
}
|
|
// Paint the background
|
|
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
|
|
|
|
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
|
|
PaintRadioButton(aPresContext, aRenderingContext, aDirtyRect);
|
|
}
|
|
|
|
// Call to the base class to draw selection borders when appropriate
|
|
return nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
PRBool nsGfxRadioControlFrame::GetRadioState()
|
|
{
|
|
return mChecked;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void nsGfxRadioControlFrame::SetRadioState(nsIPresContext* aPresContext, PRBool aValue)
|
|
{
|
|
mChecked = aValue;
|
|
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
|
|
}
|
|
|
|
void
|
|
nsGfxRadioControlFrame::InitializeControl(nsIPresContext* aPresContext)
|
|
{
|
|
nsFormControlFrame::InitializeControl(aPresContext);
|
|
|
|
// set the widget to the initial state
|
|
PRBool checked = PR_FALSE;
|
|
nsresult result = GetDefaultCheckState(&checked);
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
|
|
SetRadioState(aPresContext, checked);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// nsIStatefulFrame
|
|
//----------------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType)
|
|
{
|
|
*aStateType = nsIStatefulFrame::eRadioType;
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState)
|
|
{
|
|
// Construct a pres state.
|
|
NS_NewPresState(aState); // The addref happens here.
|
|
|
|
// This string will hold a single item, whether or not we're checked.
|
|
nsAutoString stateString;
|
|
nsFormControlHelper::GetBoolString(GetRadioState(), stateString);
|
|
(*aState)->SetStateProperty(NS_ConvertASCIItoUCS2("checked"), stateString);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState)
|
|
{
|
|
if (!mDidInit) {
|
|
mPresContext = aPresContext;
|
|
InitializeControl(aPresContext);
|
|
mDidInit = PR_TRUE;
|
|
}
|
|
|
|
mIsRestored = PR_TRUE;
|
|
nsAutoString string;
|
|
aState->GetStateProperty(NS_ConvertASCIItoUCS2("checked"), string);
|
|
SetProperty(aPresContext, nsHTMLAtoms::checked, string);
|
|
mRestoredChecked = mChecked;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// Extra Debug Helper Methods
|
|
//----------------------------------------------------------------------
|
|
#ifdef DEBUG_rodsXXX
|
|
NS_IMETHODIMP
|
|
nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext,
|
|
nsHTMLReflowMetrics& aDesiredSize,
|
|
const nsHTMLReflowState& aReflowState,
|
|
nsReflowStatus& aStatus)
|
|
{
|
|
DO_GLOBAL_REFLOW_COUNT("nsGfxRadioControlFrame", aReflowState.reason);
|
|
|
|
nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
|
|
|
COMPARE_QUIRK_SIZE("nsGfxRadioControlFrame", 12, 11)
|
|
return rv;
|
|
}
|
|
#endif
|