Not part of build.

This commit is contained in:
hyatt%netscape.com 2001-02-15 21:15:21 +00:00
parent 166b2d86e7
commit d0e0589b0d
9 changed files with 241 additions and 35 deletions

View File

@ -32,7 +32,7 @@
<outlinercol id="Col2" value="Col2" flex="1"/>
<outlinercol id="Col3" value="Col3" flex="1"/>
<outlinercol id="Col4" value="Col4" flex="1"/>
<outlinerbody flex="1" onselect="alert('sel changed!')"/>
<outlinerbody flex="1" onselect="dump('selection changed!\n')"/>
</outliner>
<hbox>

View File

@ -42,8 +42,10 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
// Toggle the selection state of the row at the specified index.
void toggleSelect(in long index);
// Select the range specified by the indices.
void rangedSelect(in long startIndex, in long endIndex);
// Select the range specified by the indices. If augment is true,
// then we add the range to the selection without clearing out anything
// else. If augment is false, everything is cleared except for the specified range.
void rangedSelect(in long startIndex, in long endIndex, in boolean augment);
// Clears the selection.
void clearSelection();

View File

@ -56,6 +56,7 @@ interface nsIOutlinerView : nsISupports
// and if so, whether an open or closed twisty should be used.
boolean isContainer(in long index);
boolean isContainerOpen(in long index);
boolean isContainerEmpty(in long index);
// The level is an integer value that represents
// the level of indentation. It is multiplied by the width specified in the
@ -73,7 +74,7 @@ interface nsIOutlinerView : nsISupports
void toggleOpenState(in long index);
// Called on the view when a header is clicked.
void cycleHeader(in nsIDOMElement elt);
void cycleHeader(in wstring colID, in nsIDOMElement elt);
// Should be called from a XUL onselect handler whenever the selection changes.
// XXX Should this be done automatically?
@ -82,6 +83,13 @@ interface nsIOutlinerView : nsISupports
// Called on the view when a cell in a non-selectable cycling column (e.g., unread/flag/etc.) is clicked.
void cycleCell(in long row, in wstring colID);
// APIs for inline editing. isEditable is called to ask the view if the cell contents are
// editable. A value of true will result in the outliner popping up a text field when the
// user tries to inline edit the cell.
// setCellText is called when the contents of the cell have been edited by the user.
boolean isEditable(in long row, in wstring colID);
void setCellText(in long row, in wstring colID, in wstring value);
// A command API that can be used to invoke commands on the selection. The outliner
// will automatically invoke this method when certain keys are pressed. For example,
// when the DEL key is pressed, performAction will be called with the "delete" string.

View File

@ -63,6 +63,55 @@ struct nsOutlinerRange
mNext = aNext;
};
void RemoveRange(PRInt32 aStart, PRInt32 aEnd) {
// See if this range overlaps.
if (aStart >= mMin && aStart <= mMax) {
// We start within this range.
// Do we also end within this range?
if (aEnd >= mMin && aEnd <= mMax) {
// We do. This range should be split into
// two new ranges.
PRInt32 aNewStart = aEnd+1;
PRInt32 aNewEnd = mMax;
mMax = aStart-1;
nsOutlinerRange* range = new nsOutlinerRange(mSelection, aNewStart, aNewEnd);
range->Connect(this, mNext);
return; // We're done, since we were entirely contained within this range.
}
else {
// The end goes outside our range. We should
// move our max down to before the start.
mMax = aStart-1;
if (mNext)
mNext->RemoveRange(aStart, aEnd);
}
}
else if (aEnd >= mMin && aEnd <= mMax) {
// The start precedes our range, but the end is contained
// within us. Pull the range up past the end.
mMin = aEnd+1;
return; // We're done, since we contained the end.
}
else {
// Neither the start nor the end was contained inside us.
// Do the start and end encompass us instead?
if (mMin >= aStart && mMax <= aEnd) {
// They do. We should simply be excised from the list.
if (mPrev)
mPrev->mNext = mNext;
else
mSelection->mFirstRange = mNext;
if (mNext)
mNext->mPrev = mPrev;
mPrev = mNext = nsnull;
delete this;
}
if (mNext)
mNext->RemoveRange(aStart, aEnd);
}
};
void Remove(PRInt32 aIndex) {
if (aIndex >= mMin && aIndex <= mMax) {
// We have found the range that contains us.
@ -161,6 +210,15 @@ struct nsOutlinerRange
else if (mNext)
mNext->RemoveAllBut(aIndex);
};
void Insert(nsOutlinerRange* aRange) {
if (mMin >= aRange->mMax)
aRange->Connect(mPrev, this);
else if (mNext)
mNext->Insert(aRange);
else
aRange->Connect(this, nsnull);
};
};
nsOutlinerSelection::nsOutlinerSelection(nsIOutlinerBoxObject* aOutliner)
@ -256,20 +314,33 @@ NS_IMETHODIMP nsOutlinerSelection::ToggleSelect(PRInt32 aIndex)
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndIndex)
NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aAugment)
{
// Clear our selection.
mFirstRange->Invalidate();
delete mFirstRange;
if (!aAugment) {
// Clear our selection.
mFirstRange->Invalidate();
delete mFirstRange;
}
if (aStartIndex == -1)
aStartIndex = mCurrentIndex;
PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
mFirstRange = new nsOutlinerRange(this, start, end);
mFirstRange->Invalidate();
if (aAugment) {
// We need to remove all the items within our selected range from the selection,
// and then we insert our new range into the list.
mFirstRange->RemoveRange(start, end);
}
nsOutlinerRange* range = new nsOutlinerRange(this, start, end);
range->Invalidate();
if (aAugment && mFirstRange)
mFirstRange->Insert(range);
else
mFirstRange = range;
FireOnSelectHandler();
@ -317,14 +388,35 @@ NS_IMETHODIMP nsOutlinerSelection::SelectAll()
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::GetRangeCount(PRInt32 *_retval)
NS_IMETHODIMP nsOutlinerSelection::GetRangeCount(PRInt32* aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
PRInt32 count = 0;
nsOutlinerRange* curr = mFirstRange;
while (curr) {
count++;
curr = curr->mNext;
}
*aResult = count;
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::GetRangeAt(PRInt32 i, PRInt32 *min, PRInt32 *max)
NS_IMETHODIMP nsOutlinerSelection::GetRangeAt(PRInt32 aIndex, PRInt32* aMin, PRInt32* aMax)
{
return NS_ERROR_NOT_IMPLEMENTED;
*aMin = *aMax = -1;
PRInt32 i = -1;
nsOutlinerRange* curr = mFirstRange;
while (curr) {
i++;
if (i == aIndex) {
*aMin = curr->mMin;
*aMax = curr->mMax;
break;
}
curr = curr->mNext;
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::GetSelectEventsSuppressed(PRBool *aSelectEventsSuppressed)

View File

@ -42,8 +42,10 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
// Toggle the selection state of the row at the specified index.
void toggleSelect(in long index);
// Select the range specified by the indices.
void rangedSelect(in long startIndex, in long endIndex);
// Select the range specified by the indices. If augment is true,
// then we add the range to the selection without clearing out anything
// else. If augment is false, everything is cleared except for the specified range.
void rangedSelect(in long startIndex, in long endIndex, in boolean augment);
// Clears the selection.
void clearSelection();

View File

@ -56,6 +56,7 @@ interface nsIOutlinerView : nsISupports
// and if so, whether an open or closed twisty should be used.
boolean isContainer(in long index);
boolean isContainerOpen(in long index);
boolean isContainerEmpty(in long index);
// The level is an integer value that represents
// the level of indentation. It is multiplied by the width specified in the
@ -73,7 +74,7 @@ interface nsIOutlinerView : nsISupports
void toggleOpenState(in long index);
// Called on the view when a header is clicked.
void cycleHeader(in nsIDOMElement elt);
void cycleHeader(in wstring colID, in nsIDOMElement elt);
// Should be called from a XUL onselect handler whenever the selection changes.
// XXX Should this be done automatically?
@ -82,6 +83,13 @@ interface nsIOutlinerView : nsISupports
// Called on the view when a cell in a non-selectable cycling column (e.g., unread/flag/etc.) is clicked.
void cycleCell(in long row, in wstring colID);
// APIs for inline editing. isEditable is called to ask the view if the cell contents are
// editable. A value of true will result in the outliner popping up a text field when the
// user tries to inline edit the cell.
// setCellText is called when the contents of the cell have been edited by the user.
boolean isEditable(in long row, in wstring colID);
void setCellText(in long row, in wstring colID, in wstring value);
// A command API that can be used to invoke commands on the selection. The outliner
// will automatically invoke this method when certain keys are pressed. For example,
// when the DEL key is pressed, performAction will be called with the "delete" string.

View File

@ -63,6 +63,55 @@ struct nsOutlinerRange
mNext = aNext;
};
void RemoveRange(PRInt32 aStart, PRInt32 aEnd) {
// See if this range overlaps.
if (aStart >= mMin && aStart <= mMax) {
// We start within this range.
// Do we also end within this range?
if (aEnd >= mMin && aEnd <= mMax) {
// We do. This range should be split into
// two new ranges.
PRInt32 aNewStart = aEnd+1;
PRInt32 aNewEnd = mMax;
mMax = aStart-1;
nsOutlinerRange* range = new nsOutlinerRange(mSelection, aNewStart, aNewEnd);
range->Connect(this, mNext);
return; // We're done, since we were entirely contained within this range.
}
else {
// The end goes outside our range. We should
// move our max down to before the start.
mMax = aStart-1;
if (mNext)
mNext->RemoveRange(aStart, aEnd);
}
}
else if (aEnd >= mMin && aEnd <= mMax) {
// The start precedes our range, but the end is contained
// within us. Pull the range up past the end.
mMin = aEnd+1;
return; // We're done, since we contained the end.
}
else {
// Neither the start nor the end was contained inside us.
// Do the start and end encompass us instead?
if (mMin >= aStart && mMax <= aEnd) {
// They do. We should simply be excised from the list.
if (mPrev)
mPrev->mNext = mNext;
else
mSelection->mFirstRange = mNext;
if (mNext)
mNext->mPrev = mPrev;
mPrev = mNext = nsnull;
delete this;
}
if (mNext)
mNext->RemoveRange(aStart, aEnd);
}
};
void Remove(PRInt32 aIndex) {
if (aIndex >= mMin && aIndex <= mMax) {
// We have found the range that contains us.
@ -161,6 +210,15 @@ struct nsOutlinerRange
else if (mNext)
mNext->RemoveAllBut(aIndex);
};
void Insert(nsOutlinerRange* aRange) {
if (mMin >= aRange->mMax)
aRange->Connect(mPrev, this);
else if (mNext)
mNext->Insert(aRange);
else
aRange->Connect(this, nsnull);
};
};
nsOutlinerSelection::nsOutlinerSelection(nsIOutlinerBoxObject* aOutliner)
@ -256,20 +314,33 @@ NS_IMETHODIMP nsOutlinerSelection::ToggleSelect(PRInt32 aIndex)
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndIndex)
NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aAugment)
{
// Clear our selection.
mFirstRange->Invalidate();
delete mFirstRange;
if (!aAugment) {
// Clear our selection.
mFirstRange->Invalidate();
delete mFirstRange;
}
if (aStartIndex == -1)
aStartIndex = mCurrentIndex;
PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
mFirstRange = new nsOutlinerRange(this, start, end);
mFirstRange->Invalidate();
if (aAugment) {
// We need to remove all the items within our selected range from the selection,
// and then we insert our new range into the list.
mFirstRange->RemoveRange(start, end);
}
nsOutlinerRange* range = new nsOutlinerRange(this, start, end);
range->Invalidate();
if (aAugment && mFirstRange)
mFirstRange->Insert(range);
else
mFirstRange = range;
FireOnSelectHandler();
@ -317,14 +388,35 @@ NS_IMETHODIMP nsOutlinerSelection::SelectAll()
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::GetRangeCount(PRInt32 *_retval)
NS_IMETHODIMP nsOutlinerSelection::GetRangeCount(PRInt32* aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
PRInt32 count = 0;
nsOutlinerRange* curr = mFirstRange;
while (curr) {
count++;
curr = curr->mNext;
}
*aResult = count;
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::GetRangeAt(PRInt32 i, PRInt32 *min, PRInt32 *max)
NS_IMETHODIMP nsOutlinerSelection::GetRangeAt(PRInt32 aIndex, PRInt32* aMin, PRInt32* aMax)
{
return NS_ERROR_NOT_IMPLEMENTED;
*aMin = *aMax = -1;
PRInt32 i = -1;
nsOutlinerRange* curr = mFirstRange;
while (curr) {
i++;
if (i == aIndex) {
*aMin = curr->mMin;
*aMax = curr->mMax;
break;
}
curr = curr->mNext;
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::GetSelectEventsSuppressed(PRBool *aSelectEventsSuppressed)

View File

@ -60,14 +60,15 @@
var col = {};
var b = this.parentNode.outlinerBoxObject;
b.getCellAt(event.clientX, event.clientY, row, col);
if (event.ctrlKey || event.metaKey) {
var augment = event.ctrlKey || event.metaKey;
if (event.shiftKey) {
b.selection.rangedSelect(-1, row.value, augment);
b.currentIndex = row.value;
}
else if (augment) {
b.selection.toggleSelect(row.value);
b.selection.currentIndex = row.value;
}
else if (event.shiftKey) {
b.selection.rangedSelect(-1, row.value);
b.currentIndex = row.value;
}
else {
/* We want to deselect all the selected items except what was
clicked, UNLESS it was a right-click. We have to do this
@ -103,7 +104,7 @@
<xul:image class="outlinercol-sortdirection"/>
</content>
<handlers>
<handler event="click" action="this.parentNode.outlinerBoxObject.view.cycleHeader(this)"/>
<handler event="click" action="this.parentNode.outlinerBoxObject.view.cycleHeader(this.id, this)"/>
</handlers>
</binding>

View File

@ -14,6 +14,7 @@
* {
display: block;
-moz-user-select: none;
}
*, *[disabled="true"] {