Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/layout/xul/tree/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

Quelle  nsTreeColumns.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "nsTreeColumns.h"
#include "nsTreeUtils.h"
#include "mozilla/ComputedStyle.h"
#include "nsContentUtils.h"
#include "nsTreeBodyFrame.h"
#include "mozilla/dom/Element.h"
#include "mozilla/CSSOrderAwareFrameIterator.h"
#include "mozilla/dom/TreeColumnBinding.h"
#include "mozilla/dom/TreeColumnsBinding.h"
#include "mozilla/dom/XULTreeElement.h"

using namespace mozilla;
using namespace mozilla::dom;

// Column class that caches all the info about our column.
nsTreeColumn::nsTreeColumn(nsTreeColumns* aColumns, dom::Element* aElement)
    : mContent(aElement), mColumns(aColumns), mIndex(0), mPrevious(nullptr) {
  NS_ASSERTION(aElement && aElement->NodeInfo()->Equals(nsGkAtoms::treecol,
                                                        kNameSpaceID_XUL),
               "nsTreeColumn's content must be a ");

  Invalidate(IgnoreErrors());
}

nsTreeColumn::~nsTreeColumn() {
  if (mNext) {
    mNext->SetPrevious(nullptr);
  }
}

NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_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_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(nsISupports)
  NS_INTERFACE_MAP_ENTRY_CONCRETE(nsTreeColumn)
NS_INTERFACE_MAP_END

nsIFrame* nsTreeColumn::GetFrame() { 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;
  }

  *aResult = frame->GetRect();
  if (frame->StyleVisibility()->IsCollapse()) {
    aResult->SizeTo(nsSize());
  }
  aResult->y = aY;
  aResult->height = aHeight;
  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;
  return NS_OK;
}

void nsTreeColumn::GetId(nsAString& aId) const { aId = GetId(); }

void nsTreeColumn::Invalidate(ErrorResult& aRv) {
  nsIFrame* frame = GetFrame();
  if (NS_WARN_IF(!frame)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  // Fetch the Id.
  mContent->GetAttr(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 == StyleTextAlign::Start &&
       vis->mDirection == StyleDirection::Rtl) ||
      (mTextAlignment == StyleTextAlign::End &&
       vis->mDirection == StyleDirection::Ltr)) {
    mTextAlignment = StyleTextAlign::Right;
  } else if (mTextAlignment == StyleTextAlign::Start ||
             mTextAlignment == StyleTextAlign::End) {
    mTextAlignment = StyleTextAlign::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);

  mOverflow = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::overflow,
                                    nsGkAtoms::_true, eCaseMatters);

  // Figure out our column type. Default type is text.
  mType = TreeColumn_Binding::TYPE_TEXT;
  static Element::AttrValuesArray typestrings[] = {nsGkAtoms::checkbox,
                                                   nullptr};
  switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
                                    typestrings, eCaseMatters)) {
    case 0:
      mType = TreeColumn_Binding::TYPE_CHECKBOX;
      break;
  }

  // Fetch the crop style.
  mCropStyle = 0;
  static Element::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;
  }
}

nsIContent* nsTreeColumn::GetParentObject() const { return mContent; }

/* virtual */
JSObject* nsTreeColumn::WrapObject(JSContext* aCx,
                                   JS::Handle<JSObject*> aGivenProto) {
  return dom::TreeColumn_Binding::Wrap(aCx, this, aGivenProto);
}

Element* nsTreeColumn::Element() { return mContent; }

int32_t nsTreeColumn::GetX(mozilla::ErrorResult& aRv) {
  nsIFrame* frame = GetFrame();
  if (NS_WARN_IF(!frame)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return 0;
  }

  return nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().x);
}

int32_t nsTreeColumn::GetWidth(mozilla::ErrorResult& aRv) {
  nsIFrame* frame = GetFrame();
  if (NS_WARN_IF(!frame)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return 0;
  }

  return nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().width);
}

already_AddRefed<nsTreeColumn> nsTreeColumn::GetPreviousColumn() {
  return do_AddRef(mPrevious);
}

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(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::TreeColumns_Binding::Wrap(aCx, this, aGivenProto);
}

XULTreeElement* nsTreeColumns::GetTree() const {
  if (!mTree) {
    return nullptr;
  }

  return XULTreeElement::FromNodeOrNull(mTree->GetBaseElement());
}

uint32_t nsTreeColumns::Count() {
  EnsureColumns();
  uint32_t count = 0;
  for (nsTreeColumn* currCol = mFirstColumn; currCol;
       currCol = currCol->GetNext()) {
    ++count;
  }
  return count;
}

nsTreeColumn* nsTreeColumns::GetLastColumn() {
  EnsureColumns();
  nsTreeColumn* currCol = mFirstColumn;
  while (currCol) {
    nsTreeColumn* next = currCol->GetNext();
    if (!next) {
      return currCol;
    }
    currCol = next;
  }
  return nullptr;
}

nsTreeColumn* nsTreeColumns::GetSortedColumn() {
  EnsureColumns();
  for (nsTreeColumn* currCol = mFirstColumn; currCol;
       currCol = currCol->GetNext()) {
    if (nsContentUtils::HasNonEmptyAttr(currCol->mContent, kNameSpaceID_None,
                                        nsGkAtoms::sortDirection)) {
      return currCol;
    }
  }
  return nullptr;
}

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->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
                                       nsGkAtoms::_true, eCaseMatters)) {
      continue;
    }

    // Skip non-text column
    if (currCol->GetType() != TreeColumn_Binding::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;
}

nsTreeColumn* nsTreeColumns::GetColumnFor(dom::Element* aElement) {
  EnsureColumns();
  for (nsTreeColumn* currCol = mFirstColumn; currCol;
       currCol = currCol->GetNext()) {
    if (currCol->mContent == aElement) {
      return currCol;
    }
  }
  return nullptr;
}

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);
}

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);
}

void nsTreeColumns::InvalidateColumns() {
  for (nsTreeColumn* currCol = mFirstColumn; currCol;
       currCol = currCol->GetNext()) {
    currCol->SetColumns(nullptr);
  }
  mFirstColumn = nullptr;
}

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();
    if (!treeContent) {
      return;
    }

    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 || !colFrame->GetContent()) {
      return;
    }

    nsTreeColumn* currCol = nullptr;

    // Enumerate the columns in visible order
    CSSOrderAwareFrameIterator iter(
        colFrame, FrameChildListID::Principal,
        CSSOrderAwareFrameIterator::ChildFilter::IncludeAll);
    for (; !iter.AtEnd(); iter.Next()) {
      nsIFrame* colFrame = iter.get();
      nsIContent* colContent = colFrame->GetContent();
      if (!colContent->IsXULElement(nsGkAtoms::treecol)) {
        continue;
      }
      // Create a new column structure.
      nsTreeColumn* col = new nsTreeColumn(this, colContent->AsElement());

      if (currCol) {
        currCol->SetNext(col);
        col->SetPrevious(currCol);
      } else {
        mFirstColumn = col;
      }
      currCol = col;
    }
  }
}

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.