NS_IMETHODIMP nsTreeSelection::ToggleSelect(PRInt32 aIndex) { // 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. mShiftSelectPivot = -1; SetCurrentIndex(aIndex); nsresult rv = NS_OK; if (!mFirstRange) Select(aIndex); else { if (!mFirstRange->Contains(aIndex)) { PRBool single; GetSingle(&single); if (!single) rv = mFirstRange->Add(aIndex); } else rv = mFirstRange->Remove(aIndex); if (NS_SUCCEEDED(rv)) { mTree->InvalidateRow(aIndex); FireOnSelectHandler(); } } return rv; }
NS_IMETHODIMP nsTreeSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aAugment) { PRBool single; nsresult rv = GetSingle(&single); if (NS_FAILED(rv)) return rv; if ((mFirstRange || (aStartIndex != aEndIndex)) && single) return NS_OK; if (!aAugment) { // Clear our selection. if (mFirstRange) { mFirstRange->Invalidate(); delete mFirstRange; mFirstRange = nsnull; } } if (aStartIndex == -1) { if (mShiftSelectPivot != -1) aStartIndex = mShiftSelectPivot; else if (mCurrentIndex != -1) aStartIndex = mCurrentIndex; else aStartIndex = aEndIndex; } mShiftSelectPivot = aStartIndex; rv = SetCurrentIndex(aEndIndex); if (NS_FAILED(rv)) return rv; PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex; PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex; if (aAugment && mFirstRange) { // 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; } nsTreeRange* range = new nsTreeRange(this, start, end); if (!range) return NS_ERROR_OUT_OF_MEMORY; range->Invalidate(); if (aAugment && mFirstRange) mFirstRange->Insert(range); else mFirstRange = range; FireOnSelectHandler(); return NS_OK; }
NS_IMETHODIMP nsTreeSelection::ClearRange(PRInt32 aStartIndex, PRInt32 aEndIndex) { SetCurrentIndex(aEndIndex); if (mFirstRange) { PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex; PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex; mFirstRange->RemoveRange(start, end); mTree->InvalidateRange(start, end); } return NS_OK; }
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::Select(PRInt32 aIndex) { mShiftSelectPivot = -1; nsresult rv = SetCurrentIndex(aIndex); if (NS_FAILED(rv)) return rv; if (mFirstRange) { PRBool alreadySelected = mFirstRange->Contains(aIndex); if (alreadySelected) { PRInt32 count = mFirstRange->Count(); if (count > 1) { // We need to deselect everything but our item. mFirstRange->RemoveAllBut(aIndex); FireOnSelectHandler(); } return NS_OK; } else { // Clear out our selection. mFirstRange->Invalidate(); delete mFirstRange; } } // Create our new selection. mFirstRange = new nsTreeRange(this, aIndex); if (!mFirstRange) return NS_ERROR_OUT_OF_MEMORY; mFirstRange->Invalidate(); // Fire the select event FireOnSelectHandler(); return NS_OK; }