mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
765
layout/xul/tree/nsTreeColumns.cpp
Normal file
765
layout/xul/tree/nsTreeColumns.cpp
Normal file
|
|
@ -0,0 +1,765 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIBoxObject.h"
|
||||
#include "nsTreeColumns.h"
|
||||
#include "nsTreeUtils.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsTreeBodyFrame.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TreeBoxObject.h"
|
||||
#include "mozilla/dom/TreeColumnBinding.h"
|
||||
#include "mozilla/dom/TreeColumnsBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// Column class that caches all the info about our column.
|
||||
nsTreeColumn::nsTreeColumn(nsTreeColumns* aColumns, nsIContent* aContent)
|
||||
: mContent(aContent),
|
||||
mColumns(aColumns),
|
||||
mPrevious(nullptr)
|
||||
{
|
||||
NS_ASSERTION(aContent &&
|
||||
aContent->NodeInfo()->Equals(nsGkAtoms::treecol,
|
||||
kNameSpaceID_XUL),
|
||||
"nsTreeColumn's content must be a <xul:treecol>");
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
nsTreeColumn::~nsTreeColumn()
|
||||
{
|
||||
if (mNext) {
|
||||
mNext->SetPrevious(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeColumn)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeColumn)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContent)
|
||||
if (tmp->mNext) {
|
||||
tmp->mNext->SetPrevious(nullptr);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNext)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeColumn)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsTreeColumn)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumn)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumn)
|
||||
|
||||
// QueryInterface implementation for nsTreeColumn
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumn)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsITreeColumn)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
if (aIID.Equals(NS_GET_IID(nsTreeColumn))) {
|
||||
AddRef();
|
||||
*aInstancePtr = this;
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsIFrame*
|
||||
nsTreeColumn::GetFrame()
|
||||
{
|
||||
NS_ENSURE_TRUE(mContent, nullptr);
|
||||
|
||||
return mContent->GetPrimaryFrame();
|
||||
}
|
||||
|
||||
bool
|
||||
nsTreeColumn::IsLastVisible(nsTreeBodyFrame* aBodyFrame)
|
||||
{
|
||||
NS_ASSERTION(GetFrame(), "should have checked for this already");
|
||||
|
||||
// cyclers are fixed width, don't adjust them
|
||||
if (IsCycler())
|
||||
return false;
|
||||
|
||||
// we're certainly not the last visible if we're not visible
|
||||
if (GetFrame()->GetRect().width == 0)
|
||||
return false;
|
||||
|
||||
// try to find a visible successor
|
||||
for (nsTreeColumn *next = GetNext(); next; next = next->GetNext()) {
|
||||
nsIFrame* frame = next->GetFrame();
|
||||
if (frame && frame->GetRect().width > 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTreeColumn::GetRect(nsTreeBodyFrame* aBodyFrame, nscoord aY, nscoord aHeight, nsRect* aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) {
|
||||
*aResult = nsRect();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool isRTL = aBodyFrame->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
|
||||
*aResult = frame->GetRect();
|
||||
aResult->y = aY;
|
||||
aResult->height = aHeight;
|
||||
if (isRTL)
|
||||
aResult->x += aBodyFrame->mAdjustWidth;
|
||||
else if (IsLastVisible(aBodyFrame))
|
||||
aResult->width += aBodyFrame->mAdjustWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTreeColumn::GetXInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) {
|
||||
*aResult = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*aResult = frame->GetRect().x;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTreeColumn::GetWidthInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) {
|
||||
*aResult = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*aResult = frame->GetRect().width;
|
||||
if (IsLastVisible(aBodyFrame))
|
||||
*aResult += aBodyFrame->mAdjustWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetElement(nsIDOMElement** aElement)
|
||||
{
|
||||
if (mContent) {
|
||||
return CallQueryInterface(mContent, aElement);
|
||||
}
|
||||
*aElement = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetColumns(nsITreeColumns** aColumns)
|
||||
{
|
||||
NS_IF_ADDREF(*aColumns = mColumns);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetX(int32_t* aX)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
*aX = nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().x);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetWidth(int32_t* aWidth)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
*aWidth = nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().width);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetId(nsAString& aId)
|
||||
{
|
||||
aId = GetId();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetIdConst(const char16_t** aIdConst)
|
||||
{
|
||||
*aIdConst = mId.get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetAtom(nsIAtom** aAtom)
|
||||
{
|
||||
NS_IF_ADDREF(*aAtom = GetAtom());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetIndex(int32_t* aIndex)
|
||||
{
|
||||
*aIndex = GetIndex();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetPrimary(bool* aPrimary)
|
||||
{
|
||||
*aPrimary = IsPrimary();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetCycler(bool* aCycler)
|
||||
{
|
||||
*aCycler = IsCycler();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetEditable(bool* aEditable)
|
||||
{
|
||||
*aEditable = IsEditable();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetSelectable(bool* aSelectable)
|
||||
{
|
||||
*aSelectable = IsSelectable();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetType(int16_t* aType)
|
||||
{
|
||||
*aType = GetType();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetNext(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetNext());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::GetPrevious(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetPrevious());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumn::Invalidate()
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
// Fetch the Id.
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, mId);
|
||||
|
||||
// If we have an Id, cache the Id as an atom.
|
||||
if (!mId.IsEmpty()) {
|
||||
mAtom = NS_Atomize(mId);
|
||||
}
|
||||
|
||||
// Cache our index.
|
||||
nsTreeUtils::GetColumnIndex(mContent, &mIndex);
|
||||
|
||||
const nsStyleVisibility* vis = frame->StyleVisibility();
|
||||
|
||||
// Cache our text alignment policy.
|
||||
const nsStyleText* textStyle = frame->StyleText();
|
||||
|
||||
mTextAlignment = textStyle->mTextAlign;
|
||||
// START or END alignment sometimes means RIGHT
|
||||
if ((mTextAlignment == NS_STYLE_TEXT_ALIGN_START &&
|
||||
vis->mDirection == NS_STYLE_DIRECTION_RTL) ||
|
||||
(mTextAlignment == NS_STYLE_TEXT_ALIGN_END &&
|
||||
vis->mDirection == NS_STYLE_DIRECTION_LTR)) {
|
||||
mTextAlignment = NS_STYLE_TEXT_ALIGN_RIGHT;
|
||||
} else if (mTextAlignment == NS_STYLE_TEXT_ALIGN_START ||
|
||||
mTextAlignment == NS_STYLE_TEXT_ALIGN_END) {
|
||||
mTextAlignment = NS_STYLE_TEXT_ALIGN_LEFT;
|
||||
}
|
||||
|
||||
// Figure out if we're the primary column (that has to have indentation
|
||||
// and twisties drawn.
|
||||
mIsPrimary = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::primary,
|
||||
nsGkAtoms::_true, eCaseMatters);
|
||||
|
||||
// Figure out if we're a cycling column (one that doesn't cause a selection
|
||||
// to happen).
|
||||
mIsCycler = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::cycler,
|
||||
nsGkAtoms::_true, eCaseMatters);
|
||||
|
||||
mIsEditable = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
|
||||
nsGkAtoms::_true, eCaseMatters);
|
||||
|
||||
mIsSelectable = !mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::selectable,
|
||||
nsGkAtoms::_false, eCaseMatters);
|
||||
|
||||
mOverflow = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::overflow,
|
||||
nsGkAtoms::_true, eCaseMatters);
|
||||
|
||||
// Figure out our column type. Default type is text.
|
||||
mType = nsITreeColumn::TYPE_TEXT;
|
||||
static nsIContent::AttrValuesArray typestrings[] =
|
||||
{&nsGkAtoms::checkbox, &nsGkAtoms::progressmeter, &nsGkAtoms::password,
|
||||
nullptr};
|
||||
switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
|
||||
typestrings, eCaseMatters)) {
|
||||
case 0: mType = nsITreeColumn::TYPE_CHECKBOX; break;
|
||||
case 1: mType = nsITreeColumn::TYPE_PROGRESSMETER; break;
|
||||
case 2: mType = nsITreeColumn::TYPE_PASSWORD; break;
|
||||
}
|
||||
|
||||
// Fetch the crop style.
|
||||
mCropStyle = 0;
|
||||
static nsIContent::AttrValuesArray cropstrings[] =
|
||||
{&nsGkAtoms::center, &nsGkAtoms::left, &nsGkAtoms::start, nullptr};
|
||||
switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::crop,
|
||||
cropstrings, eCaseMatters)) {
|
||||
case 0:
|
||||
mCropStyle = 1;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
mCropStyle = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsTreeColumn::GetParentObject() const
|
||||
{
|
||||
return mContent;
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
nsTreeColumn::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return dom::TreeColumnBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
mozilla::dom::Element*
|
||||
nsTreeColumn::GetElement(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
aRv = GetElement(getter_AddRefs(element));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(element);
|
||||
return node->AsElement();
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsTreeColumn::GetX(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
int32_t x;
|
||||
aRv = GetX(&x);
|
||||
return x;
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsTreeColumn::GetWidth(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
int32_t width;
|
||||
aRv = GetWidth(&width);
|
||||
return width;
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeColumn::Invalidate(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
aRv = Invalidate();
|
||||
}
|
||||
|
||||
nsTreeColumns::nsTreeColumns(nsTreeBodyFrame* aTree)
|
||||
: mTree(aTree)
|
||||
{
|
||||
}
|
||||
|
||||
nsTreeColumns::~nsTreeColumns()
|
||||
{
|
||||
nsTreeColumns::InvalidateColumns();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsTreeColumns)
|
||||
|
||||
// QueryInterface implementation for nsTreeColumns
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumns)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsITreeColumns)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumns)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumns)
|
||||
|
||||
nsIContent*
|
||||
nsTreeColumns::GetParentObject() const
|
||||
{
|
||||
return mTree ? mTree->GetBaseElement() : nullptr;
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
nsTreeColumns::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return dom::TreeColumnsBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
dom::TreeBoxObject*
|
||||
nsTreeColumns::GetTree() const
|
||||
{
|
||||
return mTree ? static_cast<mozilla::dom::TreeBoxObject*>(mTree->GetTreeBoxObject()) : nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetTree(nsITreeBoxObject** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetTree());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsTreeColumns::Count()
|
||||
{
|
||||
EnsureColumns();
|
||||
uint32_t count = 0;
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetCount(int32_t* _retval)
|
||||
{
|
||||
*_retval = Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetLength(int32_t* _retval)
|
||||
{
|
||||
*_retval = Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetFirstColumn(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetFirstColumn());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetLastColumn()
|
||||
{
|
||||
EnsureColumns();
|
||||
nsTreeColumn* currCol = mFirstColumn;
|
||||
while (currCol) {
|
||||
nsTreeColumn* next = currCol->GetNext();
|
||||
if (!next) {
|
||||
return currCol;
|
||||
}
|
||||
currCol = next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetLastColumn(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetLastColumn());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetPrimaryColumn(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetPrimaryColumn());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetSortedColumn()
|
||||
{
|
||||
EnsureColumns();
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
if (currCol->mContent &&
|
||||
nsContentUtils::HasNonEmptyAttr(currCol->mContent, kNameSpaceID_None,
|
||||
nsGkAtoms::sortDirection)) {
|
||||
return currCol;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetSortedColumn(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetSortedColumn());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetKeyColumn()
|
||||
{
|
||||
EnsureColumns();
|
||||
|
||||
nsTreeColumn* first = nullptr;
|
||||
nsTreeColumn* primary = nullptr;
|
||||
nsTreeColumn* sorted = nullptr;
|
||||
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
// Skip hidden columns.
|
||||
if (!currCol->mContent ||
|
||||
currCol->mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
|
||||
nsGkAtoms::_true, eCaseMatters))
|
||||
continue;
|
||||
|
||||
// Skip non-text column
|
||||
if (currCol->GetType() != nsITreeColumn::TYPE_TEXT)
|
||||
continue;
|
||||
|
||||
if (!first)
|
||||
first = currCol;
|
||||
|
||||
if (nsContentUtils::HasNonEmptyAttr(currCol->mContent, kNameSpaceID_None,
|
||||
nsGkAtoms::sortDirection)) {
|
||||
// Use sorted column as the key.
|
||||
sorted = currCol;
|
||||
break;
|
||||
}
|
||||
|
||||
if (currCol->IsPrimary())
|
||||
if (!primary)
|
||||
primary = currCol;
|
||||
}
|
||||
|
||||
if (sorted)
|
||||
return sorted;
|
||||
if (primary)
|
||||
return primary;
|
||||
return first;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetKeyColumn(nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetKeyColumn());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetColumnFor(dom::Element* aElement)
|
||||
{
|
||||
EnsureColumns();
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
if (currCol->mContent == aElement) {
|
||||
return currCol;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetColumnFor(nsIDOMElement* aElement, nsITreeColumn** _retval)
|
||||
{
|
||||
nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
|
||||
NS_ADDREF(*_retval = GetColumnFor(element));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::NamedGetter(const nsAString& aId, bool& aFound)
|
||||
{
|
||||
EnsureColumns();
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
if (currCol->GetId().Equals(aId)) {
|
||||
aFound = true;
|
||||
return currCol;
|
||||
}
|
||||
}
|
||||
aFound = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetNamedColumn(const nsAString& aId)
|
||||
{
|
||||
bool dummy;
|
||||
return NamedGetter(aId, dummy);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetNamedColumn(const nsAString& aId, nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetNamedColumn(aId));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeColumns::GetSupportedNames(nsTArray<nsString>& aNames)
|
||||
{
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
aNames.AppendElement(currCol->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::IndexedGetter(uint32_t aIndex, bool& aFound)
|
||||
{
|
||||
EnsureColumns();
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
if (currCol->GetIndex() == static_cast<int32_t>(aIndex)) {
|
||||
aFound = true;
|
||||
return currCol;
|
||||
}
|
||||
}
|
||||
aFound = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetColumnAt(uint32_t aIndex)
|
||||
{
|
||||
bool dummy;
|
||||
return IndexedGetter(aIndex, dummy);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::GetColumnAt(int32_t aIndex, nsITreeColumn** _retval)
|
||||
{
|
||||
NS_IF_ADDREF(*_retval = GetColumnAt(static_cast<uint32_t>(aIndex)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::InvalidateColumns()
|
||||
{
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol;
|
||||
currCol = currCol->GetNext()) {
|
||||
currCol->SetColumns(nullptr);
|
||||
}
|
||||
mFirstColumn = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeColumns::RestoreNaturalOrder()
|
||||
{
|
||||
if (!mTree)
|
||||
return NS_OK;
|
||||
|
||||
nsIContent* content = mTree->GetBaseElement();
|
||||
|
||||
// Strong ref, since we'll be setting attributes
|
||||
nsCOMPtr<nsIContent> colsContent =
|
||||
nsTreeUtils::GetImmediateChild(content, nsGkAtoms::treecols);
|
||||
if (!colsContent)
|
||||
return NS_OK;
|
||||
|
||||
for (uint32_t i = 0; i < colsContent->GetChildCount(); ++i) {
|
||||
nsCOMPtr<nsIContent> child = colsContent->GetChildAt(i);
|
||||
nsAutoString ordinal;
|
||||
ordinal.AppendInt(i);
|
||||
child->SetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, ordinal, true);
|
||||
}
|
||||
|
||||
nsTreeColumns::InvalidateColumns();
|
||||
|
||||
if (mTree) {
|
||||
mTree->Invalidate();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTreeColumn*
|
||||
nsTreeColumns::GetPrimaryColumn()
|
||||
{
|
||||
EnsureColumns();
|
||||
for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) {
|
||||
if (currCol->IsPrimary()) {
|
||||
return currCol;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeColumns::EnsureColumns()
|
||||
{
|
||||
if (mTree && !mFirstColumn) {
|
||||
nsIContent* treeContent = mTree->GetBaseElement();
|
||||
nsIContent* colsContent =
|
||||
nsTreeUtils::GetDescendantChild(treeContent, nsGkAtoms::treecols);
|
||||
if (!colsContent)
|
||||
return;
|
||||
|
||||
nsIContent* colContent =
|
||||
nsTreeUtils::GetDescendantChild(colsContent, nsGkAtoms::treecol);
|
||||
if (!colContent)
|
||||
return;
|
||||
|
||||
nsIFrame* colFrame = colContent->GetPrimaryFrame();
|
||||
if (!colFrame)
|
||||
return;
|
||||
|
||||
colFrame = colFrame->GetParent();
|
||||
if (!colFrame)
|
||||
return;
|
||||
|
||||
colFrame = colFrame->PrincipalChildList().FirstChild();
|
||||
if (!colFrame)
|
||||
return;
|
||||
|
||||
// Now that we have the first visible column,
|
||||
// we can enumerate the columns in visible order
|
||||
nsTreeColumn* currCol = nullptr;
|
||||
while (colFrame) {
|
||||
nsIContent* colContent = colFrame->GetContent();
|
||||
|
||||
if (colContent->NodeInfo()->Equals(nsGkAtoms::treecol,
|
||||
kNameSpaceID_XUL)) {
|
||||
// Create a new column structure.
|
||||
nsTreeColumn* col = new nsTreeColumn(this, colContent);
|
||||
if (!col)
|
||||
return;
|
||||
|
||||
if (currCol) {
|
||||
currCol->SetNext(col);
|
||||
col->SetPrevious(currCol);
|
||||
}
|
||||
else {
|
||||
mFirstColumn = col;
|
||||
}
|
||||
currCol = col;
|
||||
}
|
||||
|
||||
colFrame = colFrame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue