Files
Mozilla/mozilla/layout/html/table/src/nsTableColGroup.cpp
buster 937b504950 minor updates and fixes
git-svn-id: svn://10.0.0.236/trunk@3993 18797224-902f-48f8-a5cc-f745e15eee43
1998-06-17 19:51:51 +00:00

382 lines
11 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsTableColGroup.h"
#include "nsTableColGroupFrame.h"
#include "nsTableCol.h"
#include "nsTablePart.h"
#include "nsContainerFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
#ifdef NS_DEBUG
static PRBool gsDebug = PR_FALSE;
static PRBool gsNoisyRefs = PR_FALSE;
#else
static const PRBool gsDebug = PR_FALSE;
static const PRBool gsNoisyRefs = PR_FALSE;
#endif
nsTableColGroup::nsTableColGroup(nsIAtom* aTag, int aSpan)
: nsTableContent(aTag),
mSpan(aSpan),
mStartColIndex(0),
mColCount(0)
{
}
nsTableColGroup::nsTableColGroup (PRBool aImplicit)
: nsTableContent(NS_NewAtom(nsTablePart::kColGroupTagString)),
mSpan(0),
mStartColIndex(0),
mColCount(0)
{
mImplicit = aImplicit;
}
nsTableColGroup::~nsTableColGroup()
{
}
// Added for debuging purposes -- remove from final build
nsrefcnt nsTableColGroup::AddRef(void)
{
if (gsNoisyRefs==PR_TRUE)
printf("Add Ref: %x, nsTableColGroup cnt = %d \n",this,mRefCnt+1);
return ++mRefCnt;
}
nsrefcnt nsTableColGroup::Release(void)
{
if (gsNoisyRefs==PR_TRUE)
if (gsNoisyRefs==PR_TRUE) printf("Release: %x, nsTableColGroup cnt = %d \n",this,mRefCnt-1);
if (--mRefCnt == 0) {
if (gsNoisyRefs==PR_TRUE) printf("Delete: %x, nsTableColGroup \n",this);
delete this;
return 0;
}
return mRefCnt;
}
/** returns the number of columns represented by this group.
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
int nsTableColGroup::GetColumnCount ()
{
if (0 == mColCount)
{
int count = ChildCount ();
if (0 < count)
{
for (int index = 0; index < count; index++)
{
nsIContent * child = ChildAt (index); // child: REFCNT++
NS_ASSERTION(nsnull!=child, "bad child");
// is child a column?
nsTableContent *tableContent = (nsTableContent *)child;
if (tableContent->GetType() == nsITableContent::kTableColType)
{
nsTableCol * col = (nsTableCol *)tableContent;
col->SetColumnIndex (mStartColIndex + mColCount);
mColCount += col->GetRepeat ();
}
NS_RELEASE(child); // child: REFCNT--
}
}
else
mColCount = GetSpan ();
}
return mColCount;
}
void nsTableColGroup::ResetColumns ()
{
mColCount = 0;
}
NS_IMETHODIMP
nsTableColGroup::AppendChild (nsIContent *aContent, PRBool aNotify)
{
NS_ASSERTION(nsnull!=aContent, "bad arg");
// is aContent a TableRow?
PRBool isCol = IsCol(aContent);
if (PR_FALSE==isCol)
{
// you should go talk to my parent if you want to insert something other than a column
return NS_OK;
}
nsresult result = NS_ERROR_FAILURE;
PRBool contentHandled = PR_FALSE;
// SEC: TODO verify that aContent is table content
nsTableContent *tableContent = (nsTableContent *)aContent;
PRBool isImplicit;
tableContent->IsSynthetic(isImplicit);
if (PR_FALSE==isImplicit)
{
/* if aContent is not implicit,
* and if we already have an implicit column for this actual column,
* then replace the implicit col with this actual col.
*/
PRInt32 childCount = ChildCount();
for (PRInt32 colIndex=0; colIndex<childCount; colIndex++)
{
nsTableContent *col = (nsTableContent*)ChildAt(colIndex);
NS_ASSERTION(nsnull!=col, "bad child");
PRBool colIsImplicit;
col->IsSynthetic(colIsImplicit);
if (PR_TRUE==colIsImplicit)
{
ReplaceChildAt(aContent, colIndex, aNotify);
contentHandled = PR_TRUE;
break;
}
}
}
if (PR_FALSE==contentHandled)
result = nsTableContent::AppendChild (aContent, aNotify);
if (NS_OK==result)
{
((nsTableCol *)aContent)->SetColGroup (this);
((nsTableCol *)aContent)->SetColumnIndex (mStartColIndex + mColCount);
ResetColumns ();
}
return NS_OK;
}
NS_IMETHODIMP
nsTableColGroup::InsertChildAt (nsIContent *aContent, PRInt32 aIndex,
PRBool aNotify)
{
NS_ASSERTION(nsnull!=aContent, "bad arg");
// is aContent a TableCol?
PRBool isCol = IsCol(aContent);
// if not, ignore the request to add aContent
if (PR_FALSE==isCol)
{
// you should go talk to my parent if you want to insert something other than a column
return NS_OK;
}
// if so, add the row to this group
nsresult result = nsTableContent::InsertChildAt (aContent, aIndex, aNotify);
if (NS_OK==result)
{
((nsTableCol *)aContent)->SetColGroup (this);
ResetColumns ();
}
return NS_OK;
}
NS_IMETHODIMP
nsTableColGroup::ReplaceChildAt (nsIContent * aContent, PRInt32 aIndex,
PRBool aNotify)
{
NS_ASSERTION(nsnull!=aContent, "bad arg");
NS_ASSERTION((0<=aIndex && ChildCount()>aIndex), "bad arg");
if ((nsnull==aContent) || !(0<=aIndex && ChildCount()>aIndex))
return PR_FALSE;
// is aContent a TableRow?
PRBool isCol = IsCol(aContent);
// if not, ignore the request to replace the child at aIndex
if (PR_FALSE==isCol)
{
// you should go talk to my parent if you want to insert something other than a column
return NS_OK;
}
nsIContent * lastChild = ChildAt (aIndex); // lastChild : REFCNT++
NS_ASSERTION(nsnull!=lastChild, "bad child");
nsresult result = nsTableContent::ReplaceChildAt (aContent, aIndex, aNotify);
if (NS_OK==result)
{
((nsTableCol *)aContent)->SetColGroup (this);
if (nsnull != lastChild)
((nsTableCol *)lastChild)->SetColGroup (nsnull);
ResetColumns ();
}
NS_RELEASE(lastChild); // lastChild : REFCNT--
return NS_OK;
}
/**
* Remove a child at the given position. The method is ignored if
* the index is invalid (too small or too large).
*/
NS_IMETHODIMP
nsTableColGroup::RemoveChildAt (PRInt32 aIndex, PRBool aNotify)
{
NS_ASSERTION((0<=aIndex && ChildCount()>aIndex), "bad arg");
nsIContent * lastChild = ChildAt (aIndex); // lastChild: REFCNT++
NS_ASSERTION(nsnull!=lastChild, "bad child");
nsresult result = nsTableContent::RemoveChildAt (aIndex, aNotify);
if (NS_OK==result)
{
if (nsnull != lastChild)
((nsTableCol *)lastChild)->SetColGroup (nsnull);
ResetColumns ();
}
NS_IF_RELEASE(lastChild); // lastChild REFCNT--
return NS_OK;
}
/** support method to determine if the param aContent is a TableRow object */
PRBool nsTableColGroup::IsCol(nsIContent * aContent) const
{
NS_ASSERTION(nsnull!=aContent, "bad arg");
PRBool result = PR_FALSE;
if (nsnull!=aContent)
{
// is aContent a col?
nsTableContent *tableContent = (nsTableContent *)aContent;
const int contentType = tableContent->GetType();
if (contentType == nsITableContent::kTableColType)
result = PR_TRUE;
}
return result;
}
void nsTableColGroup::SetAttribute(nsIAtom* aAttribute, const nsString& aValue)
{
nsHTMLValue val;
if (aAttribute == nsHTMLAtoms::width)
{
ParseValueOrPercentOrProportional(aValue, val, eHTMLUnit_Pixel);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if ( aAttribute == nsHTMLAtoms::span)
{
ParseValue(aValue, 0, val, eHTMLUnit_Integer);
nsHTMLTagContent::SetAttribute(aAttribute, val);
SetSpan(val.GetIntValue());
}
else if (aAttribute == nsHTMLAtoms::align) {
nsHTMLValue val;
if (ParseTableAlignParam(aValue, val)) {
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
return;
}
else if (aAttribute == nsHTMLAtoms::valign) {
nsHTMLValue val;
if (ParseTableAlignParam(aValue, val)) {
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
return;
}
}
void nsTableColGroup::MapAttributesInto(nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
NS_PRECONDITION(nsnull!=aContext, "bad style context arg");
NS_PRECONDITION(nsnull!=aPresContext, "bad presentation context arg");
if (nsnull != mAttributes) {
float p2t;
nsHTMLValue value;
nsStyleText* textStyle = nsnull;
// width
GetAttribute(nsHTMLAtoms::width, value);
if (value.GetUnit() != eHTMLUnit_Null) {
nsStylePosition* position = (nsStylePosition*)
aContext->GetMutableStyleData(eStyleStruct_Position);
switch (value.GetUnit()) {
case eHTMLUnit_Percent:
position->mWidth.SetPercentValue(value.GetPercentValue());
break;
case eHTMLUnit_Pixel:
p2t = aPresContext->GetPixelsToTwips();
position->mWidth.SetCoordValue(nscoord(p2t * (float)value.GetPixelValue()));
break;
}
}
// align: enum
GetAttribute(nsHTMLAtoms::align, value);
if (value.GetUnit() == eHTMLUnit_Enumerated)
{
textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text);
textStyle->mTextAlign = value.GetIntValue();
}
// valign: enum
GetAttribute(nsHTMLAtoms::valign, value);
if (value.GetUnit() == eHTMLUnit_Enumerated)
{
if (nsnull==textStyle)
textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text);
textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
}
}
}
nsresult
nsTableColGroup::CreateFrame(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aResult)
{
NS_PRECONDITION(nsnull!=aPresContext, "bad arg");
nsIFrame* frame;
nsresult rv = nsTableColGroupFrame::NewFrame(&frame, this, aParentFrame);
if (NS_OK != rv) {
return rv;
}
frame->SetStyleContext(aPresContext, aStyleContext);
aResult = frame;
return rv;
}
/* ---------- Global Functions ---------- */
NS_HTML nsresult
NS_NewTableColGroupPart(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* body = new nsTableColGroup(aTag, 0);
if (nsnull == body) {
return NS_ERROR_OUT_OF_MEMORY;
}
return body->QueryInterface(kIHTMLContentIID, (void **) aInstancePtrResult);
}