123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765 |
- /* -*- 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_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();
- }
- }
- }
|