gecko-dev/layout/xul/tree/nsTreeSelection.cpp

868 строки
22 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2012-05-21 15:12:37 +04:00
/* 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/. */
2001-02-14 22:39:20 +03:00
#include "mozilla/AsyncEventDispatcher.h"
2001-02-14 22:39:20 +03:00
#include "nsCOMPtr.h"
#include "nsTreeSelection.h"
#include "nsIBoxObject.h"
#include "nsITreeBoxObject.h"
#include "nsITreeView.h"
2001-02-15 12:43:11 +03:00
#include "nsString.h"
#include "nsIDOMElement.h"
#include "nsDOMClassInfoID.h"
2001-02-15 12:43:11 +03:00
#include "nsIContent.h"
#include "nsNameSpaceManager.h"
#include "nsGkAtoms.h"
#include "nsAutoPtr.h"
#include "nsComponentManagerUtils.h"
2001-02-14 22:39:20 +03:00
using namespace mozilla;
2001-02-14 23:16:02 +03:00
// A helper class for managing our ranges of selection.
struct nsTreeRange
2001-02-14 23:16:02 +03:00
{
nsTreeSelection* mSelection;
2001-02-14 23:16:02 +03:00
nsTreeRange* mPrev;
nsTreeRange* mNext;
2001-02-14 23:16:02 +03:00
int32_t mMin;
int32_t mMax;
2001-02-15 00:38:17 +03:00
nsTreeRange(nsTreeSelection* aSel, int32_t aSingleVal)
:mSelection(aSel), mPrev(nullptr), mNext(nullptr), mMin(aSingleVal), mMax(aSingleVal) {}
nsTreeRange(nsTreeSelection* aSel, int32_t aMin, int32_t aMax)
:mSelection(aSel), mPrev(nullptr), mNext(nullptr), mMin(aMin), mMax(aMax) {}
2001-02-14 23:16:02 +03:00
~nsTreeRange() { delete mNext; }
2001-02-14 23:16:02 +03:00
void Connect(nsTreeRange* aPrev = nullptr, nsTreeRange* aNext = nullptr) {
2001-02-15 12:43:11 +03:00
if (aPrev)
aPrev->mNext = this;
else
mSelection->mFirstRange = this;
if (aNext)
aNext->mPrev = this;
2001-02-14 23:16:02 +03:00
mPrev = aPrev;
mNext = aNext;
}
2001-02-14 23:26:18 +03:00
nsresult RemoveRange(int32_t aStart, int32_t aEnd) {
// This should so be a loop... sigh...
// We start past the range to remove, so no more to remove
if (aEnd < mMin)
return NS_OK;
// We are the last range to be affected
if (aEnd < mMax) {
if (aStart <= mMin) {
// Just chop the start of the range off
mMin = aEnd + 1;
} else {
// We need to split the range
nsTreeRange* range = new nsTreeRange(mSelection, aEnd + 1, mMax);
if (!range)
return NS_ERROR_OUT_OF_MEMORY;
mMax = aStart - 1;
2001-02-16 00:15:21 +03:00
range->Connect(this, mNext);
}
return NS_OK;
2001-02-16 00:15:21 +03:00
}
nsTreeRange* next = mNext;
if (aStart <= mMin) {
// The remove includes us, remove ourselves from the list
if (mPrev)
mPrev->mNext = next;
else
mSelection->mFirstRange = next;
if (next)
next->mPrev = mPrev;
mPrev = mNext = nullptr;
delete this;
} else if (aStart <= mMax) {
// Just chop the end of the range off
mMax = aStart - 1;
2001-02-16 00:15:21 +03:00
}
return next ? next->RemoveRange(aStart, aEnd) : NS_OK;
}
2001-02-16 00:15:21 +03:00
nsresult Remove(int32_t aIndex) {
2001-02-15 12:43:11 +03:00
if (aIndex >= mMin && aIndex <= mMax) {
// We have found the range that contains us.
if (mMin == mMax) {
// Delete the whole range.
if (mPrev)
mPrev->mNext = mNext;
if (mNext)
mNext->mPrev = mPrev;
nsTreeRange* first = mSelection->mFirstRange;
2001-02-15 12:43:11 +03:00
if (first == this)
mSelection->mFirstRange = mNext;
mNext = mPrev = nullptr;
2001-02-15 12:43:11 +03:00
delete this;
}
else if (aIndex == mMin)
mMin++;
else if (aIndex == mMax)
mMax--;
else {
// We have to break this range.
nsTreeRange* newRange = new nsTreeRange(mSelection, aIndex + 1, mMax);
if (!newRange)
return NS_ERROR_OUT_OF_MEMORY;
newRange->Connect(this, mNext);
mMax = aIndex - 1;
}
2001-02-15 12:43:11 +03:00
}
else if (mNext)
return mNext->Remove(aIndex);
return NS_OK;
}
2001-02-15 12:43:11 +03:00
nsresult Add(int32_t aIndex) {
2001-02-15 12:43:11 +03:00
if (aIndex < mMin) {
// We have found a spot to insert.
if (aIndex + 1 == mMin)
mMin = aIndex;
else if (mPrev && mPrev->mMax+1 == aIndex)
mPrev->mMax = aIndex;
else {
// We have to create a new range.
nsTreeRange* newRange = new nsTreeRange(mSelection, aIndex);
if (!newRange)
return NS_ERROR_OUT_OF_MEMORY;
2001-02-15 12:43:11 +03:00
newRange->Connect(mPrev, this);
}
}
else if (mNext)
mNext->Add(aIndex);
else {
// Insert on to the end.
if (mMax+1 == aIndex)
mMax = aIndex;
else {
// We have to create a new range.
nsTreeRange* newRange = new nsTreeRange(mSelection, aIndex);
if (!newRange)
return NS_ERROR_OUT_OF_MEMORY;
newRange->Connect(this, nullptr);
2001-02-15 12:43:11 +03:00
}
}
return NS_OK;
}
2001-02-15 12:43:11 +03:00
bool Contains(int32_t aIndex) {
2001-02-14 23:26:18 +03:00
if (aIndex >= mMin && aIndex <= mMax)
return true;
2001-02-14 23:26:18 +03:00
if (mNext)
return mNext->Contains(aIndex);
return false;
}
2001-02-15 00:38:17 +03:00
int32_t Count() {
int32_t total = mMax - mMin + 1;
2001-02-15 00:38:17 +03:00
if (mNext)
total += mNext->Count();
return total;
}
2001-02-15 00:38:17 +03:00
static void CollectRanges(nsTreeRange* aRange, nsTArray<int32_t>& aRanges)
{
nsTreeRange* cur = aRange;
while (cur) {
aRanges.AppendElement(cur->mMin);
aRanges.AppendElement(cur->mMax);
cur = cur->mNext;
}
}
static void InvalidateRanges(nsITreeBoxObject* aTree,
nsTArray<int32_t>& aRanges)
{
if (aTree) {
nsCOMPtr<nsITreeBoxObject> tree = aTree;
for (uint32_t i = 0; i < aRanges.Length(); i += 2) {
aTree->InvalidateRange(aRanges[i], aRanges[i + 1]);
}
}
}
2001-02-15 00:38:17 +03:00
void Invalidate() {
nsTArray<int32_t> ranges;
CollectRanges(this, ranges);
InvalidateRanges(mSelection->mTree, ranges);
}
2001-02-15 00:38:17 +03:00
void RemoveAllBut(int32_t aIndex) {
2001-02-15 00:38:17 +03:00
if (aIndex >= mMin && aIndex <= mMax) {
2001-02-15 12:43:11 +03:00
// Invalidate everything in this list.
nsTArray<int32_t> ranges;
CollectRanges(mSelection->mFirstRange, ranges);
2001-02-15 12:43:11 +03:00
2001-02-15 00:38:17 +03:00
mMin = aIndex;
mMax = aIndex;
nsTreeRange* first = mSelection->mFirstRange;
2001-02-15 00:38:17 +03:00
if (mPrev)
mPrev->mNext = mNext;
if (mNext)
mNext->mPrev = mPrev;
mNext = mPrev = nullptr;
2001-02-15 00:38:17 +03:00
2001-02-15 12:43:11 +03:00
if (first != this) {
delete mSelection->mFirstRange;
mSelection->mFirstRange = this;
}
InvalidateRanges(mSelection->mTree, ranges);
2001-02-15 00:38:17 +03:00
}
else if (mNext)
mNext->RemoveAllBut(aIndex);
}
2001-02-16 00:15:21 +03:00
void Insert(nsTreeRange* aRange) {
2001-02-16 00:15:21 +03:00
if (mMin >= aRange->mMax)
aRange->Connect(mPrev, this);
else if (mNext)
mNext->Insert(aRange);
else
aRange->Connect(this, nullptr);
}
2001-02-14 23:16:02 +03:00
};
nsTreeSelection::nsTreeSelection(nsITreeBoxObject* aTree)
: mTree(aTree),
mSuppressed(false),
mCurrentIndex(-1),
mShiftSelectPivot(-1),
mFirstRange(nullptr)
2001-02-14 22:39:20 +03:00
{
}
nsTreeSelection::~nsTreeSelection()
2001-02-14 22:39:20 +03:00
{
2001-02-15 00:38:17 +03:00
delete mFirstRange;
if (mSelectTimer)
mSelectTimer->Cancel();
2001-02-14 22:39:20 +03:00
}
NS_IMPL_CYCLE_COLLECTION(nsTreeSelection, mTree, mCurrentColumn)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeSelection)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeSelection)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeSelection)
NS_INTERFACE_MAP_ENTRY(nsITreeSelection)
NS_INTERFACE_MAP_ENTRY(nsINativeTreeSelection)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TreeSelection)
NS_INTERFACE_MAP_END
NS_IMETHODIMP nsTreeSelection::GetTree(nsITreeBoxObject * *aTree)
2001-02-14 22:39:20 +03:00
{
NS_IF_ADDREF(*aTree = mTree);
2001-02-14 22:39:20 +03:00
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::SetTree(nsITreeBoxObject * aTree)
2001-02-14 22:39:20 +03:00
{
if (mSelectTimer) {
mSelectTimer->Cancel();
mSelectTimer = nullptr;
}
// Make sure aTree really implements nsITreeBoxObject and nsIBoxObject!
nsCOMPtr<nsIBoxObject> bo = do_QueryInterface(aTree);
mTree = do_QueryInterface(bo);
NS_ENSURE_STATE(mTree == aTree);
2001-02-14 22:39:20 +03:00
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::GetSingle(bool* aSingle)
{
if (!mTree)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
nsCOMPtr<nsIDOMElement> element;
boxObject->GetElement(getter_AddRefs(element));
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
static nsIContent::AttrValuesArray strings[] =
{&nsGkAtoms::single, &nsGkAtoms::cell, &nsGkAtoms::text, nullptr};
*aSingle = content->FindAttrValueIn(kNameSpaceID_None,
nsGkAtoms::seltype,
strings, eCaseMatters) >= 0;
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::IsSelected(int32_t aIndex, bool* aResult)
2001-02-14 22:39:20 +03:00
{
2001-02-14 23:26:18 +03:00
if (mFirstRange)
*aResult = mFirstRange->Contains(aIndex);
else
*aResult = false;
2001-02-14 23:26:18 +03:00
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::TimedSelect(int32_t aIndex, int32_t aMsec)
2001-02-16 05:21:34 +03:00
{
bool suppressSelect = mSuppressed;
2001-02-16 05:21:34 +03:00
if (aMsec != -1)
mSuppressed = true;
2001-02-16 05:21:34 +03:00
nsresult rv = Select(aIndex);
if (NS_FAILED(rv))
return rv;
if (aMsec != -1) {
mSuppressed = suppressSelect;
if (!mSuppressed) {
if (mSelectTimer)
mSelectTimer->Cancel();
mSelectTimer = do_CreateInstance("@mozilla.org/timer;1");
mSelectTimer->InitWithFuncCallback(SelectCallback, this, aMsec,
nsITimer::TYPE_ONE_SHOT);
2001-02-16 05:21:34 +03:00
}
}
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::Select(int32_t aIndex)
2001-02-14 22:39:20 +03:00
{
2001-02-16 05:21:34 +03:00
mShiftSelectPivot = -1;
nsresult rv = SetCurrentIndex(aIndex);
if (NS_FAILED(rv))
return rv;
2001-02-15 00:38:17 +03:00
if (mFirstRange) {
bool alreadySelected = mFirstRange->Contains(aIndex);
2001-02-15 00:38:17 +03:00
if (alreadySelected) {
int32_t count = mFirstRange->Count();
2001-02-15 00:38:17 +03:00
if (count > 1) {
// We need to deselect everything but our item.
mFirstRange->RemoveAllBut(aIndex);
2001-02-15 12:43:11 +03:00
FireOnSelectHandler();
2001-02-15 00:38:17 +03:00
}
2001-02-15 12:43:11 +03:00
return NS_OK;
}
else {
// Clear out our selection.
mFirstRange->Invalidate();
delete mFirstRange;
2001-02-15 00:38:17 +03:00
}
}
2001-02-15 12:43:11 +03:00
// Create our new selection.
mFirstRange = new nsTreeRange(this, aIndex);
if (!mFirstRange)
return NS_ERROR_OUT_OF_MEMORY;
2001-02-15 12:43:11 +03:00
mFirstRange->Invalidate();
2001-02-15 00:38:17 +03:00
2001-02-15 12:43:11 +03:00
// Fire the select event
FireOnSelectHandler();
2001-02-15 00:38:17 +03:00
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::ToggleSelect(int32_t aIndex)
2001-02-14 22:39:20 +03:00
{
2001-02-15 12:43:11 +03:00
// There are six cases that can occur on a ToggleSelect with our
// range code.
// (1) A new range should be made for a selection.
// (2) A single range is removed from the selection.
// (3) The item is added to an existing range.
// (4) The item is removed from an existing range.
// (5) The addition of the item causes two ranges to be merged.
// (6) The removal of the item causes two ranges to be split.
2001-02-16 05:21:34 +03:00
mShiftSelectPivot = -1;
nsresult rv = SetCurrentIndex(aIndex);
if (NS_FAILED(rv))
return rv;
2001-02-16 05:21:34 +03:00
2001-02-15 12:43:11 +03:00
if (!mFirstRange)
Select(aIndex);
else {
if (!mFirstRange->Contains(aIndex)) {
bool single;
rv = GetSingle(&single);
if (NS_SUCCEEDED(rv) && !single)
rv = mFirstRange->Add(aIndex);
}
else
rv = mFirstRange->Remove(aIndex);
if (NS_SUCCEEDED(rv)) {
if (mTree)
mTree->InvalidateRow(aIndex);
2001-02-15 12:43:11 +03:00
FireOnSelectHandler();
}
2001-02-15 12:43:11 +03:00
}
return rv;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::RangedSelect(int32_t aStartIndex, int32_t aEndIndex, bool aAugment)
2001-02-14 22:39:20 +03:00
{
bool single;
nsresult rv = GetSingle(&single);
if (NS_FAILED(rv))
return rv;
if ((mFirstRange || (aStartIndex != aEndIndex)) && single)
return NS_OK;
2001-02-16 00:15:21 +03:00
if (!aAugment) {
// Clear our selection.
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nullptr;
}
2001-02-16 00:15:21 +03:00
}
2001-02-16 05:21:34 +03:00
if (aStartIndex == -1) {
if (mShiftSelectPivot != -1)
aStartIndex = mShiftSelectPivot;
else if (mCurrentIndex != -1)
aStartIndex = mCurrentIndex;
else
aStartIndex = aEndIndex;
2001-02-16 05:21:34 +03:00
}
mShiftSelectPivot = aStartIndex;
rv = SetCurrentIndex(aEndIndex);
if (NS_FAILED(rv))
return rv;
2001-02-16 05:21:34 +03:00
int32_t start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
int32_t end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
2001-02-15 12:43:11 +03:00
if (aAugment && mFirstRange) {
2001-02-16 00:15:21 +03:00
// We need to remove all the items within our selected range from the selection,
// and then we insert our new range into the list.
nsresult rv = mFirstRange->RemoveRange(start, end);
if (NS_FAILED(rv))
return rv;
2001-02-16 00:15:21 +03:00
}
nsTreeRange* range = new nsTreeRange(this, start, end);
if (!range)
return NS_ERROR_OUT_OF_MEMORY;
2001-02-16 00:15:21 +03:00
range->Invalidate();
if (aAugment && mFirstRange)
mFirstRange->Insert(range);
else
mFirstRange = range;
2001-02-15 12:43:11 +03:00
FireOnSelectHandler();
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::ClearRange(int32_t aStartIndex, int32_t aEndIndex)
{
nsresult rv = SetCurrentIndex(aEndIndex);
if (NS_FAILED(rv))
return rv;
if (mFirstRange) {
int32_t start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
int32_t end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
mFirstRange->RemoveRange(start, end);
if (mTree)
mTree->InvalidateRange(start, end);
}
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::ClearSelection()
2001-02-14 22:39:20 +03:00
{
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nullptr;
}
2001-02-16 05:21:34 +03:00
mShiftSelectPivot = -1;
2001-02-15 12:43:11 +03:00
FireOnSelectHandler();
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::InvertSelection()
2001-02-14 22:39:20 +03:00
{
2001-02-15 12:43:11 +03:00
return NS_ERROR_NOT_IMPLEMENTED;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::SelectAll()
2001-02-14 22:39:20 +03:00
{
if (!mTree)
return NS_OK;
nsCOMPtr<nsITreeView> view;
mTree->GetView(getter_AddRefs(view));
2001-02-15 12:43:11 +03:00
if (!view)
return NS_OK;
int32_t rowCount;
2001-02-15 12:43:11 +03:00
view->GetRowCount(&rowCount);
bool single;
nsresult rv = GetSingle(&single);
if (NS_FAILED(rv))
return rv;
if (rowCount == 0 || (rowCount > 1 && single))
2001-02-15 12:43:11 +03:00
return NS_OK;
mShiftSelectPivot = -1;
// Invalidate not necessary when clearing selection, since
// we're going to invalidate the world on the SelectAll.
delete mFirstRange;
mFirstRange = new nsTreeRange(this, 0, rowCount-1);
2001-02-15 12:43:11 +03:00
mFirstRange->Invalidate();
FireOnSelectHandler();
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::GetRangeCount(int32_t* aResult)
2001-02-14 22:39:20 +03:00
{
int32_t count = 0;
nsTreeRange* curr = mFirstRange;
2001-02-16 00:15:21 +03:00
while (curr) {
count++;
curr = curr->mNext;
}
*aResult = count;
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::GetRangeAt(int32_t aIndex, int32_t* aMin, int32_t* aMax)
2001-02-14 22:39:20 +03:00
{
2001-02-16 00:15:21 +03:00
*aMin = *aMax = -1;
int32_t i = -1;
nsTreeRange* curr = mFirstRange;
2001-02-16 00:15:21 +03:00
while (curr) {
i++;
if (i == aIndex) {
*aMin = curr->mMin;
*aMax = curr->mMax;
break;
}
curr = curr->mNext;
}
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::GetCount(int32_t *count)
{
if (mFirstRange)
*count = mFirstRange->Count();
else // No range available, so there's no selected row.
*count = 0;
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::GetSelectEventsSuppressed(bool *aSelectEventsSuppressed)
2001-02-14 22:44:38 +03:00
{
*aSelectEventsSuppressed = mSuppressed;
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::SetSelectEventsSuppressed(bool aSelectEventsSuppressed)
2001-02-14 22:44:38 +03:00
{
mSuppressed = aSelectEventsSuppressed;
2001-02-16 05:21:34 +03:00
if (!mSuppressed)
FireOnSelectHandler();
2001-02-14 22:44:38 +03:00
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::GetCurrentIndex(int32_t *aCurrentIndex)
2001-02-14 22:39:20 +03:00
{
2001-02-14 22:44:38 +03:00
*aCurrentIndex = mCurrentIndex;
return NS_OK;
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(int32_t aIndex)
2001-02-14 22:39:20 +03:00
{
if (!mTree) {
return NS_ERROR_UNEXPECTED;
}
if (mCurrentIndex == aIndex) {
return NS_OK;
}
if (mCurrentIndex != -1 && mTree)
mTree->InvalidateRow(mCurrentIndex);
2001-02-16 05:21:34 +03:00
mCurrentIndex = aIndex;
if (!mTree)
return NS_OK;
2001-02-16 05:21:34 +03:00
if (aIndex != -1)
mTree->InvalidateRow(aIndex);
2001-02-16 05:21:34 +03:00
// Fire DOMMenuItemActive or DOMMenuItemInactive event for tree.
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
NS_ASSERTION(boxObject, "no box object!");
if (!boxObject)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDOMElement> treeElt;
boxObject->GetElement(getter_AddRefs(treeElt));
nsCOMPtr<nsINode> treeDOMNode(do_QueryInterface(treeElt));
NS_ENSURE_STATE(treeDOMNode);
NS_NAMED_LITERAL_STRING(DOMMenuItemActive, "DOMMenuItemActive");
NS_NAMED_LITERAL_STRING(DOMMenuItemInactive, "DOMMenuItemInactive");
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(treeDOMNode,
(aIndex != -1 ? DOMMenuItemActive :
DOMMenuItemInactive),
true, false);
return asyncDispatcher->PostDOMEvent();
2001-02-14 22:39:20 +03:00
}
NS_IMETHODIMP nsTreeSelection::GetCurrentColumn(nsITreeColumn** aCurrentColumn)
{
NS_IF_ADDREF(*aCurrentColumn = mCurrentColumn);
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::SetCurrentColumn(nsITreeColumn* aCurrentColumn)
{
if (!mTree) {
return NS_ERROR_UNEXPECTED;
}
if (mCurrentColumn == aCurrentColumn) {
return NS_OK;
}
if (mCurrentColumn) {
if (mFirstRange)
mTree->InvalidateCell(mFirstRange->mMin, mCurrentColumn);
if (mCurrentIndex != -1)
mTree->InvalidateCell(mCurrentIndex, mCurrentColumn);
}
mCurrentColumn = aCurrentColumn;
if (mCurrentColumn) {
if (mFirstRange)
mTree->InvalidateCell(mFirstRange->mMin, mCurrentColumn);
if (mCurrentIndex != -1)
mTree->InvalidateCell(mCurrentIndex, mCurrentColumn);
}
return NS_OK;
}
#define ADD_NEW_RANGE(macro_range, macro_selection, macro_start, macro_end) \
{ \
int32_t start = macro_start; \
int32_t end = macro_end; \
if (start > end) { \
end = start; \
} \
nsTreeRange* macro_new_range = new nsTreeRange(macro_selection, start, end); \
if (macro_range) \
macro_range->Insert(macro_new_range); \
else \
macro_range = macro_new_range; \
}
NS_IMETHODIMP
nsTreeSelection::AdjustSelection(int32_t aIndex, int32_t aCount)
{
NS_ASSERTION(aCount != 0, "adjusting by zero");
if (!aCount) return NS_OK;
// adjust mShiftSelectPivot, if necessary
if ((mShiftSelectPivot != 1) && (aIndex <= mShiftSelectPivot)) {
// if we are deleting and the delete includes the shift select pivot, reset it
if (aCount < 0 && (mShiftSelectPivot <= (aIndex -aCount -1))) {
mShiftSelectPivot = -1;
}
else {
mShiftSelectPivot += aCount;
}
}
// adjust mCurrentIndex, if necessary
if ((mCurrentIndex != -1) && (aIndex <= mCurrentIndex)) {
// if we are deleting and the delete includes the current index, reset it
if (aCount < 0 && (mCurrentIndex <= (aIndex -aCount -1))) {
mCurrentIndex = -1;
}
else {
mCurrentIndex += aCount;
}
}
// no selection, so nothing to do.
if (!mFirstRange) return NS_OK;
bool selChanged = false;
nsTreeRange* oldFirstRange = mFirstRange;
nsTreeRange* curr = mFirstRange;
mFirstRange = nullptr;
while (curr) {
if (aCount > 0) {
// inserting
if (aIndex > curr->mMax) {
// adjustment happens after the range, so no change
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, curr->mMax);
}
else if (aIndex <= curr->mMin) {
// adjustment happens before the start of the range, so shift down
ADD_NEW_RANGE(mFirstRange, this, curr->mMin + aCount, curr->mMax + aCount);
selChanged = true;
}
else {
// adjustment happen inside the range.
// break apart the range and create two ranges
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, aIndex - 1);
ADD_NEW_RANGE(mFirstRange, this, aIndex + aCount, curr->mMax + aCount);
selChanged = true;
}
}
else {
// deleting
if (aIndex > curr->mMax) {
// adjustment happens after the range, so no change
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, curr->mMax);
}
else {
// remember, aCount is negative
selChanged = true;
int32_t lastIndexOfAdjustment = aIndex - aCount - 1;
if (aIndex <= curr->mMin) {
if (lastIndexOfAdjustment < curr->mMin) {
// adjustment happens before the start of the range, so shift up
ADD_NEW_RANGE(mFirstRange, this, curr->mMin + aCount, curr->mMax + aCount);
}
else if (lastIndexOfAdjustment >= curr->mMax) {
// adjustment contains the range. remove the range by not adding it to the newRange
}
else {
// adjustment starts before the range, and ends in the middle of it, so trim the range
ADD_NEW_RANGE(mFirstRange, this, aIndex, curr->mMax + aCount)
}
}
else if (lastIndexOfAdjustment >= curr->mMax) {
// adjustment starts in the middle of the current range, and contains the end of the range, so trim the range
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, aIndex - 1)
}
else {
// range contains the adjustment, so shorten the range
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, curr->mMax + aCount)
}
}
}
curr = curr->mNext;
}
delete oldFirstRange;
// Fire the select event
if (selChanged)
FireOnSelectHandler();
2001-03-08 03:46:58 +03:00
return NS_OK;
}
NS_IMETHODIMP
nsTreeSelection::InvalidateSelection()
2001-03-08 03:46:58 +03:00
{
if (mFirstRange)
mFirstRange->Invalidate();
return NS_OK;
}
NS_IMETHODIMP
nsTreeSelection::GetShiftSelectPivot(int32_t* aIndex)
{
*aIndex = mShiftSelectPivot;
return NS_OK;
}
2001-02-15 12:43:11 +03:00
nsresult
nsTreeSelection::FireOnSelectHandler()
2001-02-15 12:43:11 +03:00
{
if (mSuppressed || !mTree)
2001-02-15 12:43:11 +03:00
return NS_OK;
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
NS_ASSERTION(boxObject, "no box object!");
if (!boxObject)
return NS_ERROR_UNEXPECTED;
2001-02-15 12:43:11 +03:00
nsCOMPtr<nsIDOMElement> elt;
boxObject->GetElement(getter_AddRefs(elt));
2008-12-03 14:11:34 +03:00
NS_ENSURE_STATE(elt);
2001-02-15 12:43:11 +03:00
nsCOMPtr<nsINode> node(do_QueryInterface(elt));
NS_ENSURE_STATE(node);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(node, NS_LITERAL_STRING("select"), true, false);
asyncDispatcher->RunDOMEventWhenSafe();
2001-02-15 12:43:11 +03:00
return NS_OK;
}
void
nsTreeSelection::SelectCallback(nsITimer *aTimer, void *aClosure)
{
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsTreeSelection> self = static_cast<nsTreeSelection*>(aClosure);
if (self) {
self->FireOnSelectHandler();
aTimer->Cancel();
self->mSelectTimer = nullptr;
}
}
2001-02-15 12:43:11 +03:00
2001-02-14 22:39:20 +03:00
///////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewTreeSelection(nsITreeBoxObject* aTree, nsITreeSelection** aResult)
2001-02-14 22:39:20 +03:00
{
*aResult = new nsTreeSelection(aTree);
2001-02-14 22:39:20 +03:00
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}