Files
Mozilla/mozilla/layout/xul/base/src/nsXULTreeFrame.cpp
hyatt%netscape.com 723f41dc0e Fix for 42867. r=evaughan
git-svn-id: svn://10.0.0.236/trunk@72579 18797224-902f-48f8-a5cc-f745e15eee43
2000-06-20 00:52:57 +00:00

311 lines
8.2 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 Communicator client 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.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsXULTreeFrame.h"
#include "nsIScrollableFrame.h"
#include "nsIDOMElement.h"
#include "nsXULTreeOuterGroupFrame.h"
#include "nsXULAtoms.h"
//
// NS_NewXULTreeFrame
//
// Creates a new tree frame
//
nsresult
NS_NewXULTreeFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTreeFrame* it = new (aPresShell) nsXULTreeFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
} // NS_NewXULTreeFrame
// Constructor
nsXULTreeFrame::nsXULTreeFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal)
{
mPresShell = aPresShell;
}
// Destructor
nsXULTreeFrame::~nsXULTreeFrame()
{
}
NS_IMETHODIMP_(nsrefcnt)
nsXULTreeFrame::AddRef(void)
{
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsXULTreeFrame::Release(void)
{
return NS_OK;
}
//
// QueryInterface
//
NS_INTERFACE_MAP_BEGIN(nsXULTreeFrame)
NS_INTERFACE_MAP_ENTRY(nsITreeFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
static void
GetImmediateChild(nsIContent* aParent, nsIAtom* aTag, nsIContent** aResult)
{
*aResult = nsnull;
PRInt32 childCount;
aParent->ChildCount(childCount);
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
aParent->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (aTag == tag.get()) {
*aResult = child;
NS_ADDREF(*aResult);
return;
}
}
return;
}
NS_IMETHODIMP
nsXULTreeFrame::EnsureRowIsVisible(PRInt32 aRowIndex)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* XULTreeOuterGroup = nsnull;
GetTreeBody(&XULTreeOuterGroup);
if (!XULTreeOuterGroup) return NS_OK;
XULTreeOuterGroup->EnsureRowIsVisible(aRowIndex);
return NS_OK;
}
/* void scrollToIndex (in long rowIndex); */
NS_IMETHODIMP
nsXULTreeFrame::ScrollToIndex(PRInt32 aRowIndex)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* XULTreeOuterGroup = nsnull;
GetTreeBody(&XULTreeOuterGroup);
if (!XULTreeOuterGroup) return NS_OK;
XULTreeOuterGroup->ScrollToIndex(aRowIndex);
return NS_OK;
}
/* nsIDOMElement getNextItem (in nsIDOMElement startItem, in long delta); */
NS_IMETHODIMP
nsXULTreeFrame::GetNextItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* treeOuterGroup = nsnull;
GetTreeBody(&treeOuterGroup);
if (!treeOuterGroup)
return NS_OK; // No tree body. Just bail.
nsCOMPtr<nsIContent> start(do_QueryInterface(aStartItem));
nsCOMPtr<nsIContent> row;
GetImmediateChild(start, nsXULAtoms::treerow, getter_AddRefs(row));
nsCOMPtr<nsIContent> result;
treeOuterGroup->FindNextRowContent(aDelta, row, nsnull, getter_AddRefs(result));
if (!result)
return NS_OK;
nsCOMPtr<nsIContent> parent;
result->GetParent(*getter_AddRefs(parent));
if (!parent)
return NS_OK;
nsCOMPtr<nsIDOMElement> item(do_QueryInterface(parent));
*aResult = item;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
/* nsIDOMElement getPreviousItem (in nsIDOMElement startItem, in long delta); */
NS_IMETHODIMP
nsXULTreeFrame::GetPreviousItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* treeOuterGroup = nsnull;
GetTreeBody(&treeOuterGroup);
if (!treeOuterGroup)
return NS_OK; // No tree body. Just bail.
nsCOMPtr<nsIContent> start(do_QueryInterface(aStartItem));
nsCOMPtr<nsIContent> row;
GetImmediateChild(start, nsXULAtoms::treerow, getter_AddRefs(row));
nsCOMPtr<nsIContent> result;
treeOuterGroup->FindPreviousRowContent(aDelta, row, nsnull, getter_AddRefs(result));
if (!result)
return NS_OK;
nsCOMPtr<nsIContent> parent;
result->GetParent(*getter_AddRefs(parent));
if (!parent)
return NS_OK;
nsCOMPtr<nsIDOMElement> item(do_QueryInterface(parent));
*aResult = item;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
/* nsIDOMElement getItemAtIndex (in long index); */
NS_IMETHODIMP
nsXULTreeFrame::GetItemAtIndex(PRInt32 aIndex, nsIDOMElement **aResult)
{
*aResult = nsnull;
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* treeOuterGroup = nsnull;
GetTreeBody(&treeOuterGroup);
if (!treeOuterGroup)
return NS_OK; // No tree body. Just bail.
nsCOMPtr<nsIContent> result;
treeOuterGroup->FindRowContentAtIndex(aIndex, nsnull, getter_AddRefs(result));
if (!result)
return NS_OK;
nsCOMPtr<nsIContent> parent;
result->GetParent(*getter_AddRefs(parent));
if (!parent)
return NS_OK;
nsCOMPtr<nsIDOMElement> item(do_QueryInterface(parent));
*aResult = item;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
/* long getIndexOfItem (in nsIDOMElement item); */
NS_IMETHODIMP
nsXULTreeFrame::GetIndexOfItem(nsIPresContext* aPresContext, nsIDOMElement* aElement, PRInt32* aResult)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* treeOuterGroup = nsnull;
GetTreeBody(&treeOuterGroup);
if (!treeOuterGroup)
return NS_OK; // No tree body. Just bail.
*aResult = 0;
nsCOMPtr<nsIContent> content(do_QueryInterface(aElement));
nsCOMPtr<nsIContent> root;
treeOuterGroup->GetContent(getter_AddRefs(root));
return treeOuterGroup->IndexOfItem(root, content, PR_FALSE, PR_TRUE, aResult);
}
/* void getNumberOfVisibleRows (); */
NS_IMETHODIMP
nsXULTreeFrame::GetNumberOfVisibleRows(PRInt32 *aResult)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* XULTreeOuterGroup = nsnull;
GetTreeBody(&XULTreeOuterGroup);
if (!XULTreeOuterGroup) return NS_OK;
return XULTreeOuterGroup->GetNumberOfVisibleRows(aResult);
}
/* void getIndexOfFirstVisibleRow (); */
NS_IMETHODIMP
nsXULTreeFrame::GetIndexOfFirstVisibleRow(PRInt32 *aResult)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* XULTreeOuterGroup = nsnull;
GetTreeBody(&XULTreeOuterGroup);
if (!XULTreeOuterGroup) return NS_OK;
return XULTreeOuterGroup->GetIndexOfFirstVisibleRow(aResult);
}
NS_IMETHODIMP
nsXULTreeFrame::GetRowCount(PRInt32 *aResult)
{
// Get our treechildren child frame.
nsXULTreeOuterGroupFrame* XULTreeOuterGroup = nsnull;
GetTreeBody(&XULTreeOuterGroup);
if (!XULTreeOuterGroup) return NS_OK;
return XULTreeOuterGroup->GetRowCount(aResult);
}
void
nsXULTreeFrame::GetTreeBody(nsXULTreeOuterGroupFrame** aResult)
{
nsCOMPtr<nsIContent> child;
PRInt32 count;
mContent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
mContent->ChildAt(i, *getter_AddRefs(child));
if (child) {
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::treechildren) {
// This is our actual treechildren frame.
nsIFrame* frame;
mPresShell->GetPrimaryFrameFor(child, &frame);
if (frame) {
nsCOMPtr<nsIScrollableFrame> scroll(do_QueryInterface(frame));
if (scroll) {
scroll->GetScrolledFrame(nsnull, frame);
}
*aResult = (nsXULTreeOuterGroupFrame*)frame;
return;
}
}
}
}
*aResult = nsnull;
}