Fix for bug 296040. Cell-based selection in trees

r=Neil Deakin, sr=Neil Rashbrook, sponsored by BEToptions
This commit is contained in:
Jan.Varga%gmail.com 2006-06-06 20:05:13 +00:00
Родитель 954d75ac83
Коммит e5158d88ef
51 изменённых файлов: 1143 добавлений и 237 удалений

Просмотреть файл

@ -150,6 +150,7 @@ pageInfoTreeView.prototype = {
selectionChanged: function() { },
cycleCell: function(row, column) { },
isEditable: function(row, column) { return false; },
isSelectable: function(row, column) { return false; },
performAction: function(action) { },
performActionOnCell: function(action, row, column) { }
};

Просмотреть файл

@ -5249,6 +5249,15 @@ nsNavHistoryResultTreeViewer::IsEditable(PRInt32 row, nsITreeColumn* col,
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsNavHistoryResultTreeViewer::IsSelectable (nsITreeView)
NS_IMETHODIMP
nsNavHistoryResultTreeViewer::IsSelectable(PRInt32 row, nsITreeColumn* col,
PRBool* _retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsNavHistoryResultTreeViewer::SetCellValue (nsITreeView)

Просмотреть файл

@ -431,6 +431,10 @@ var gCookiesWindow = {
{
return false;
},
isSelectable: function (aIndex, aColumn)
{
return false;
},
setCellValue: function (aIndex, aColumn, aValue) {},
setCellText: function (aIndex, aColumn, aValue) {},
performAction: function (aAction) {},

Просмотреть файл

@ -455,6 +455,7 @@ var gDownloadActionsWindow = {
selectionChanged: function () {},
cycleCell: function (aIndex, aColumn) {},
isEditable: function (aIndex, aColumn) { return false; },
isSelectable: function (aIndex, aColumn) { return false; },
setCellValue: function (aIndex, aColumn, aValue) {},
setCellText: function (aIndex, aColumn, aValue) {},
performAction: function (aAction) {},

Просмотреть файл

@ -326,6 +326,7 @@ EngineView.prototype = {
selectionChanged: function() { },
cycleCell: function(row, column) { },
isEditable: function(index, column) { return false; },
isSelectable: function(index, column) { return false; },
setCellValue: function(index, column, value) { },
setCellText: function(index, column, value) { },
performAction: function(action) { },

Просмотреть файл

@ -77,6 +77,7 @@ GK_ATOM(accept, "accept")
GK_ATOM(acceptcharset, "accept-charset")
GK_ATOM(accesskey, "accesskey")
GK_ATOM(action, "action")
GK_ATOM(active, "active")
GK_ATOM(actuate, "actuate")
GK_ATOM(after, "after")
GK_ATOM(after_end, "after_end")
@ -153,6 +154,7 @@ GK_ATOM(capture, "capture")
GK_ATOM(caseOrder, "case-order")
GK_ATOM(cdataSectionElements, "cdata-section-elements")
GK_ATOM(ceiling, "ceiling")
GK_ATOM(cell, "cell")
GK_ATOM(cellpadding, "cellpadding")
GK_ATOM(cellspacing, "cellspacing")
GK_ATOM(center, "center")
@ -684,6 +686,7 @@ GK_ATOM(scrollbox, "scrollbox")
GK_ATOM(scrollcorner, "scrollcorner")
GK_ATOM(scrolling, "scrolling")
GK_ATOM(select, "select")
GK_ATOM(selectable, "selectable")
GK_ATOM(selected, "selected")
GK_ATOM(selectedIndex, "selectedIndex")
GK_ATOM(selectedindex, "selectedindex")

Просмотреть файл

@ -1005,6 +1005,32 @@ nsXULTreeBuilder::IsEditable(PRInt32 aRow, nsITreeColumn* aCol, PRBool* _retval)
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeBuilder::IsSelectable(PRInt32 aRow, nsITreeColumn* aCol, PRBool* _retval)
{
NS_PRECONDITION(aRow >= 0 && aRow < mRows.Count(), "bad index");
if (aRow < 0 || aRow >= mRows.Count())
return NS_ERROR_INVALID_ARG;
*_retval = PR_TRUE;
// Find the <cell> that corresponds to the column we want.
nsCOMPtr<nsIContent> cell;
GetTemplateActionCellFor(aRow, aCol, getter_AddRefs(cell));
if (cell) {
nsAutoString raw;
cell->GetAttr(kNameSpaceID_None, nsXULAtoms::selectable, raw);
nsAutoString selectable;
SubstituteText(mRows[aRow]->mMatch->mResult, raw, selectable);
if (selectable.EqualsLiteral("false"))
*_retval = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeBuilder::SetCellValue(PRInt32 aRow, nsITreeColumn* aCol, const nsAString& aValue)
{

Просмотреть файл

@ -593,6 +593,7 @@ function Startup()
},
cycleCell: function cycleCell(index, column) { itemArray[index].cycleCell(index); },
isEditable: function isEditable(index, column) { return false; },
isSelectable: function isSelectable(index, column) { return false; },
performAction: function performAction(action) { },
performActionOnCell: function performActionOnCell(action, index, column) { }
};

Просмотреть файл

@ -282,6 +282,12 @@ function bov_isedit (row, col)
return false;
}
BasicOView.prototype.isSelectable =
function bov_isselect (row, col)
{
return false;
}
BasicOView.prototype.setCellValue =
function bov_setct (row, col, value)
{
@ -506,7 +512,7 @@ function tovr_resort (leafSort)
(rowIndex + this.visualFootprint - 1));
*/
tree.tree.invalidateRange (rowIndex,
rowIndex + this.visualFootprint - 1);
rowIndex + this.visualFootprint - 1);
}
}
/*
@ -1221,6 +1227,12 @@ function tov_isedit (row, col)
return false;
}
TreeOView.prototype.isSelectable =
function tov_isselect (row, col)
{
return false;
}
TreeOView.prototype.setCellValue =
function tov_setct (row, col, value)
{

Просмотреть файл

@ -72,6 +72,7 @@ inBaseTreeView.prototype =
cycleHeader: function(aCol) {},
cycleCell: function(aRow, aCol) {},
isEditable: function(aRow, aCol) {},
isSelectable: function(aRow, aCol) {},
setCellValue: function(aRow, aCol, aValue) {},
setCellText: function(aRow, aCol, aValue) {},
performAction: function(aAction) {},

Просмотреть файл

@ -178,6 +178,10 @@ JSObjectView.prototype =
isEditable: function(aRow, aCol)
{
},
isSelectable: function(aRow, aCol)
{
},
setCellValue: function(aRow, aCol, aValue)
{

Просмотреть файл

@ -320,6 +320,12 @@ function bov_isedit (row, col)
return false;
}
BasicOView.prototype.isSelectable =
function bov_isselect (row, col)
{
return false;
}
BasicOView.prototype.setCellValue =
function bov_setct (row, col, value)
{
@ -1498,6 +1504,12 @@ function xtv_isedit (row, col)
return false;
}
XULTreeView.prototype.isSelectable =
function xtv_isselect (row, col)
{
return false;
}
XULTreeView.prototype.setCellValue =
function xtv_setct (row, col, value)
{

Просмотреть файл

@ -914,6 +914,13 @@ mozSqlResult::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
return CanUpdate(_retval);
}
NS_IMETHODIMP
mozSqlResult::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
mozSqlResult::SetCellValue(PRInt32 row, nsITreeColumn* col, const nsAString& value)
{

Просмотреть файл

@ -320,6 +320,12 @@ function bov_isedit (row, col)
return false;
}
BasicOView.prototype.isSelectable =
function bov_isselect (row, col)
{
return false;
}
BasicOView.prototype.setCellValue =
function bov_setct (row, col, value)
{
@ -1498,6 +1504,12 @@ function xtv_isedit (row, col)
return false;
}
XULTreeView.prototype.isSelectable =
function xtv_isselect (row, col)
{
return false;
}
XULTreeView.prototype.setCellValue =
function xtv_setct (row, col, value)
{

Просмотреть файл

@ -601,6 +601,13 @@ inDOMView::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
return NS_OK;
}
NS_IMETHODIMP
inDOMView::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
{
return NS_OK;
}
NS_IMETHODIMP
inDOMView::IsSeparator(PRInt32 index, PRBool *_retval)
{

Просмотреть файл

@ -47,7 +47,7 @@ interface nsITreeSelection;
interface nsITreeColumn;
interface nsITreeColumns;
[scriptable, uuid(55f3b431-1aa8-4e23-ad3d-a9f5644bdaa6)]
[scriptable, uuid(a264f607-9d90-469e-b770-1ae7284fde05)]
interface nsITreeBoxObject : nsISupports
{
/**
@ -157,6 +157,8 @@ interface nsITreeBoxObject : nsISupports
void invalidateRow(in long index);
void invalidateCell(in long row, in nsITreeColumn col);
void invalidateRange(in long startIndex, in long endIndex);
void invalidateColumnRange(in long startIndex, in long endIndex,
in nsITreeColumn col);
/**
* A hit test that can tell you what row the mouse is over.

Просмотреть файл

@ -39,7 +39,7 @@ interface nsITreeColumns;
interface nsIDOMElement;
interface nsIAtom;
[scriptable, uuid(58a8574d-15a8-4678-99a5-e1be56104093)]
[scriptable, uuid(ae835ecf-6b32-4660-9b43-8a270df56e02)]
interface nsITreeColumn : nsISupports
{
readonly attribute nsIDOMElement element;
@ -58,6 +58,7 @@ interface nsITreeColumn : nsISupports
readonly attribute boolean primary;
readonly attribute boolean cycler;
readonly attribute boolean editable;
readonly attribute boolean selectable;
const short TYPE_TEXT = 1;
const short TYPE_CHECKBOX = 2;

Просмотреть файл

@ -22,6 +22,7 @@
* Contributor(s):
* Dave Hyatt <hyatt@mozilla.org> (Original Author)
* Håkan Waara <hwaara@chello.se>
* Jan Varga <jan@mozdevgroup.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -38,10 +39,11 @@
* ***** END LICENSE BLOCK ***** */
interface nsITreeBoxObject;
interface nsITreeColumn;
#include "nsISupports.idl"
[scriptable, uuid(F8A13364-184E-4da3-BADF-5C04837537F8)]
[scriptable, uuid(ab6fe746-300b-4ab4-abb9-1c0e3977874c)]
interface nsITreeSelection : nsISupports
{
/**
@ -138,6 +140,11 @@ interface nsITreeSelection : nsISupports
*/
attribute long currentIndex;
/**
* The current column.
*/
attribute nsITreeColumn currentColumn;
/**
* The selection "pivot". This is the first item the user selected as
* part of a ranged select.

Просмотреть файл

@ -44,7 +44,7 @@
interface nsITreeSelection;
interface nsITreeColumn;
[scriptable, uuid(22f034b7-a879-43ad-baee-ba6fd4d466ce)]
[scriptable, uuid(637276b5-58c0-4eff-89ea-c7f3c5bf0b54)]
interface nsITreeView : nsISupports
{
/**
@ -197,6 +197,13 @@ interface nsITreeView : nsISupports
*/
boolean isEditable(in long row, in nsITreeColumn col);
/**
* isSelectable is called to ask the view if the cell is selectable.
* This method is only called if the selection style is |cell| or |text|.
* XXXvarga shouldn't this be called isCellSelectable?
*/
boolean isSelectable(in long row, in nsITreeColumn col);
/**
* setCellValue is called when the value of the cell has been set by the user.
* This method is only called for columns of type other than |text|.

Просмотреть файл

@ -725,7 +725,7 @@ nsTreeBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
return InvalidateRow(aStart);
PRInt32 last = GetLastVisibleRow();
if (aEnd < mTopRowIndex || aStart > last)
if (aStart > aEnd || aEnd < mTopRowIndex || aStart > last)
return NS_OK;
if (aStart < mTopRowIndex)
@ -740,6 +740,34 @@ nsTreeBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
return NS_OK;
}
NS_IMETHODIMP
nsTreeBodyFrame::InvalidateColumnRange(PRInt32 aStart, PRInt32 aEnd, nsITreeColumn* aCol)
{
if (mUpdateBatchNest)
return NS_OK;
nsTreeColumn* col = NS_STATIC_CAST(nsTreeColumn*, aCol);
if (col) {
if (aStart == aEnd)
return InvalidateCell(aStart, col);
PRInt32 last = GetLastVisibleRow();
if (aStart > aEnd || aEnd < mTopRowIndex || aStart > last)
return NS_OK;
if (aStart < mTopRowIndex)
aStart = mTopRowIndex;
if (aEnd > last)
aEnd = last;
nsRect rangeRect(col->GetX(), mInnerBox.y+mRowHeight*(aStart-mTopRowIndex), col->GetWidth(), mRowHeight*(aEnd-aStart+1));
nsIFrame::Invalidate(rangeRect, PR_FALSE);
}
return NS_OK;
}
static void
FindScrollParts(nsIFrame* aCurrFrame, nsTreeBodyFrame::ScrollParts* aResult)
{
@ -1230,6 +1258,143 @@ nsTreeBodyFrame::GetRowAt(PRInt32 aX, PRInt32 aY)
return row;
}
void
nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText,
PRInt32 aRowIndex, nsTreeColumn* aColumn,
nsIRenderingContext& aRenderingContext,
nsRect& aTextRect)
{
nscoord width;
aRenderingContext.GetWidth(aText, width);
nscoord maxWidth = aTextRect.width;
if (aColumn->Overflow()) {
nsTreeColumn* nextColumn = aColumn->GetNext();
while (nextColumn && width > maxWidth) {
while (nextColumn && nextColumn->GetWidth() == 0)
nextColumn = nextColumn->GetNext();
if (nextColumn) {
nsAutoString nextText;
mView->GetCellText(aRowIndex, nextColumn, nextText);
if (nextText.Length() == 0) {
maxWidth += nextColumn->GetWidth();
nextColumn = nextColumn->GetNext();
}
else {
nextColumn = nsnull;
}
}
}
}
if (width > maxWidth) {
// See if the width is even smaller than the ellipsis
// If so, clear the text completely.
nscoord ellipsisWidth;
aRenderingContext.GetWidth(ELLIPSIS, ellipsisWidth);
nscoord width = aTextRect.width;
if (ellipsisWidth > width)
aText.SetLength(0);
else if (ellipsisWidth == width)
aText.AssignLiteral(ELLIPSIS);
else {
// We will be drawing an ellipsis, thank you very much.
// Subtract out the required width of the ellipsis.
// This is the total remaining width we have to play with.
width -= ellipsisWidth;
// Now we crop.
switch (aColumn->GetCropStyle()) {
default:
case 0: {
// Crop right.
nscoord cwidth;
nscoord twidth = 0;
int length = aText.Length();
int i;
for (i = 0; i < length; ++i) {
PRUnichar ch = aText[i];
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
aText.Truncate(i);
aText.AppendLiteral(ELLIPSIS);
}
break;
case 2: {
// Crop left.
nscoord cwidth;
nscoord twidth = 0;
int length = aText.Length();
int i;
for (i=length-1; i >= 0; --i) {
PRUnichar ch = aText[i];
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
nsAutoString copy;
aText.Right(copy, length-1-i);
aText.AssignLiteral(ELLIPSIS);
aText += copy;
}
break;
case 1:
{
// Crop center.
nsAutoString leftStr, rightStr;
nscoord cwidth, twidth = 0;
int length = aText.Length();
int rightPos = length - 1;
for (int leftPos = 0; leftPos < rightPos; ++leftPos) {
PRUnichar ch = aText[leftPos];
aRenderingContext.GetWidth(ch, cwidth);
twidth += cwidth;
if (twidth > width)
break;
leftStr.Append(ch);
ch = aText[rightPos];
aRenderingContext.GetWidth(ch, cwidth);
twidth += cwidth;
if (twidth > width)
break;
rightStr.Insert(ch, 0);
--rightPos;
}
aText = leftStr + NS_LITERAL_STRING(ELLIPSIS) + rightStr;
}
break;
}
}
}
else {
switch (aColumn->GetTextAlignment()) {
case NS_STYLE_TEXT_ALIGN_RIGHT: {
aTextRect.x += aTextRect.width - width;
}
break;
case NS_STYLE_TEXT_ALIGN_CENTER: {
aTextRect.x += (aTextRect.width - width) / 2;
}
break;
}
}
aRenderingContext.GetWidth(aText, width);
aTextRect.width = width;
}
nsIAtom*
nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect,
PRInt32 aRowIndex,
@ -1336,9 +1501,33 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect,
return nsCSSAnonBoxes::moztreeimage;
}
// Just assume "text".
// XXX For marquee selection, we'll have to make this more precise and do text measurement.
return nsCSSAnonBoxes::moztreecelltext;
currX += iconRect.width;
remainingWidth -= iconRect.width;
nsAutoString cellText;
mView->GetCellText(aRowIndex, aColumn, cellText);
nsRect textRect(currX, cellRect.y, remainingWidth, cellRect.height);
nsStyleContext* textContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreecelltext);
nsMargin textMargin;
textContext->GetStyleMargin()->GetMargin(textMargin);
textRect.Deflate(textMargin);
AdjustForBorderPadding(textContext, textRect);
nsCOMPtr<nsIRenderingContext> renderingContext;
GetPresContext()->PresShell()->CreateRenderingContext(this, getter_AddRefs(renderingContext));
renderingContext->SetFont(textContext->GetStyleFont()->mFont, nsnull);
AdjustForCellText(cellText, aRowIndex, aColumn, *renderingContext, textRect);
if (aX >= textRect.x && aX < textRect.x + textRect.width)
return nsCSSAnonBoxes::moztreecelltext;
else
return nsCSSAnonBoxes::moztreecell;
}
void
@ -1653,6 +1842,14 @@ nsTreeBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, nsTreeColumn* aCol)
selection->GetCurrentIndex(&currentIndex);
if (aRowIndex == currentIndex)
mScratchArray->AppendElement(nsXULAtoms::current);
// active
if (aCol) {
nsCOMPtr<nsITreeColumn> currentColumn;
selection->GetCurrentColumn(getter_AddRefs(currentColumn));
if (aCol == currentColumn)
mScratchArray->AppendElement(nsXULAtoms::active);
}
}
// container or leaf
@ -3155,112 +3352,7 @@ nsTreeBodyFrame::PaintText(PRInt32 aRowIndex,
// Set our font.
aRenderingContext.SetFont(fontMet);
nscoord width;
aRenderingContext.GetWidth(text, width);
if (width > textRect.width) {
// See if the width is even smaller than the ellipsis
// If so, clear the text completely.
nscoord ellipsisWidth;
aRenderingContext.GetWidth(ELLIPSIS, ellipsisWidth);
nscoord width = textRect.width;
if (ellipsisWidth > width)
text.SetLength(0);
else if (ellipsisWidth == width)
text.AssignLiteral(ELLIPSIS);
else {
// We will be drawing an ellipsis, thank you very much.
// Subtract out the required width of the ellipsis.
// This is the total remaining width we have to play with.
width -= ellipsisWidth;
// Now we crop.
switch (aColumn->GetCropStyle()) {
default:
case 0: {
// Crop right.
nscoord cwidth;
nscoord twidth = 0;
int length = text.Length();
int i;
for (i = 0; i < length; ++i) {
PRUnichar ch = text[i];
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
text.Truncate(i);
text.AppendLiteral(ELLIPSIS);
}
break;
case 2: {
// Crop left.
nscoord cwidth;
nscoord twidth = 0;
int length = text.Length();
int i;
for (i=length-1; i >= 0; --i) {
PRUnichar ch = text[i];
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
nsAutoString copy;
text.Right(copy, length-1-i);
text.AssignLiteral(ELLIPSIS);
text += copy;
}
break;
case 1:
{
// Crop center.
nsAutoString leftStr, rightStr;
nscoord cwidth, twidth = 0;
int length = text.Length();
int rightPos = length - 1;
for (int leftPos = 0; leftPos < rightPos; ++leftPos) {
PRUnichar ch = text[leftPos];
aRenderingContext.GetWidth(ch, cwidth);
twidth += cwidth;
if (twidth > width)
break;
leftStr.Append(ch);
ch = text[rightPos];
aRenderingContext.GetWidth(ch, cwidth);
twidth += cwidth;
if (twidth > width)
break;
rightStr.Insert(ch, 0);
--rightPos;
}
text = leftStr + NS_LITERAL_STRING(ELLIPSIS) + rightStr;
}
break;
}
}
}
else {
switch (aColumn->GetTextAlignment()) {
case NS_STYLE_TEXT_ALIGN_RIGHT: {
textRect.x += textRect.width - width;
}
break;
case NS_STYLE_TEXT_ALIGN_CENTER: {
textRect.x += (textRect.width - width) / 2;
}
break;
}
}
aRenderingContext.GetWidth(text, width);
textRect.width = width;
AdjustForCellText(text, aRowIndex, aColumn, aRenderingContext, textRect);
// Subtract out the remaining width.
nsRect copyRect(textRect);
@ -3284,13 +3376,13 @@ nsTreeBodyFrame::PaintText(PRInt32 aRowIndex,
if (decorations & (NS_FONT_DECORATION_OVERLINE | NS_FONT_DECORATION_UNDERLINE)) {
fontMet->GetUnderline(offset, size);
if (decorations & NS_FONT_DECORATION_OVERLINE)
aRenderingContext.FillRect(textRect.x, textRect.y, width, size);
aRenderingContext.FillRect(textRect.x, textRect.y, textRect.width, size);
if (decorations & NS_FONT_DECORATION_UNDERLINE)
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, width, size);
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size);
}
if (decorations & NS_FONT_DECORATION_LINE_THROUGH) {
fontMet->GetStrikeout(offset, size);
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, width, size);
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size);
}
#ifdef MOZ_TIMELINE
NS_TIMELINE_START_TIMER("Render Outline Text");

Просмотреть файл

@ -230,6 +230,11 @@ protected:
// coordinate system of this frame.
PRInt32 GetRowAt(nscoord aX, nscoord aY);
void AdjustForCellText(nsAutoString& aText,
PRInt32 aRowIndex, nsTreeColumn* aColumn,
nsIRenderingContext& aRenderingContext,
nsRect& aTextRect);
// A helper used when hit testing.
nsIAtom* GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect,
PRInt32 aRowIndex, nsTreeColumn* aColumn);

Просмотреть файл

@ -396,6 +396,14 @@ NS_IMETHODIMP nsTreeBoxObject::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
return NS_OK;
}
NS_IMETHODIMP nsTreeBoxObject::InvalidateColumnRange(PRInt32 aStart, PRInt32 aEnd, nsITreeColumn* aCol)
{
nsITreeBoxObject* body = GetTreeBody();
if (body)
return body->InvalidateColumnRange(aStart, aEnd, aCol);
return NS_OK;
}
NS_IMETHODIMP nsTreeBoxObject::GetRowAt(PRInt32 x, PRInt32 y, PRInt32 *_retval)
{
nsITreeBoxObject* body = GetTreeBody();

Просмотреть файл

@ -156,6 +156,13 @@ nsTreeColumn::GetEditable(PRBool* aEditable)
return NS_OK;
}
NS_IMETHODIMP
nsTreeColumn::GetSelectable(PRBool* aSelectable)
{
*aSelectable = IsSelectable();
return NS_OK;
}
NS_IMETHODIMP
nsTreeColumn::GetType(PRInt16* aType)
{
@ -224,6 +231,12 @@ nsTreeColumn::CacheAttributes()
mIsEditable = content->AttrValueIs(kNameSpaceID_None, nsXULAtoms::editable,
nsXULAtoms::_true, eCaseMatters);
mIsSelectable = !content->AttrValueIs(kNameSpaceID_None, nsXULAtoms::selectable,
nsXULAtoms::_false, eCaseMatters);
mOverflow = content->AttrValueIs(kNameSpaceID_None, nsXULAtoms::overflow,
nsXULAtoms::_true, eCaseMatters);
// Figure out our column type. Default type is text.
mType = nsITreeColumn::TYPE_TEXT;
static nsIContent::AttrValuesArray typestrings[] =

Просмотреть файл

@ -78,6 +78,8 @@ protected:
PRBool IsPrimary() { return mIsPrimary; };
PRBool IsCycler() { return mIsCycler; };
PRBool IsEditable() { return mIsEditable; };
PRBool IsSelectable() { return mIsSelectable; };
PRBool Overflow() { return mOverflow; };
PRInt16 GetType() { return mType; };
@ -102,6 +104,8 @@ private:
PRPackedBool mIsPrimary;
PRPackedBool mIsCycler;
PRPackedBool mIsEditable;
PRPackedBool mIsSelectable;
PRPackedBool mOverflow;
PRInt16 mType;

Просмотреть файл

@ -630,7 +630,31 @@ nsTreeContentView::IsEditable(PRInt32 aRow, nsITreeColumn* aCol, PRBool* _retval
nsIContent* cell = GetCell(realRow, aCol);
if (cell && cell->AttrValueIs(kNameSpaceID_None, nsXULAtoms::editable,
nsXULAtoms::_false, eCaseMatters)) {
*_retval = PR_FALSE;
*_retval = PR_FALSE;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTreeContentView::IsSelectable(PRInt32 aRow, nsITreeColumn* aCol, PRBool* _retval)
{
NS_PRECONDITION(aRow >= 0 && aRow < mRows.Count(), "bad row");
if (aRow < 0 || aRow >= mRows.Count())
return NS_ERROR_INVALID_ARG;
*_retval = PR_TRUE;
Row* row = (Row*)mRows[aRow];
nsCOMPtr<nsIContent> realRow;
nsTreeUtils::GetImmediateChild(row->mContent, nsXULAtoms::treerow, getter_AddRefs(realRow));
if (realRow) {
nsIContent* cell = GetCell(realRow, aCol);
if (cell && cell->AttrValueIs(kNameSpaceID_None, nsXULAtoms::selectable,
nsXULAtoms::_false, eCaseMatters)) {
*_retval = PR_FALSE;
}
}

Просмотреть файл

@ -256,12 +256,12 @@ struct nsTreeRange
};
nsTreeSelection::nsTreeSelection(nsITreeBoxObject* aTree)
: mTree(aTree),
mSuppressed(PR_FALSE),
mCurrentIndex(-1),
mShiftSelectPivot(-1),
mFirstRange(nsnull)
{
mTree = aTree;
mSuppressed = PR_FALSE;
mFirstRange = nsnull;
mShiftSelectPivot = -1;
mCurrentIndex = -1;
}
nsTreeSelection::~nsTreeSelection()
@ -299,11 +299,19 @@ NS_IMETHODIMP nsTreeSelection::SetTree(nsITreeBoxObject * aTree)
NS_IMETHODIMP nsTreeSelection::GetSingle(PRBool* aSingle)
{
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
nsCOMPtr<nsIDOMElement> element;
boxObject->GetElement(getter_AddRefs(element));
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
*aSingle = content->AttrValueIs(kNameSpaceID_None, nsXULAtoms::seltype,
NS_LITERAL_STRING("single"), eCaseMatters);
static nsIContent::AttrValuesArray strings[] =
{&nsXULAtoms::single, &nsXULAtoms::cell, &nsXULAtoms::text, nsnull};
*aSingle = content->FindAttrValueIn(kNameSpaceID_None,
nsXULAtoms::seltype,
strings, eCaseMatters) >= 0;
return NS_OK;
}
@ -621,6 +629,37 @@ NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(PRInt32 aIndex)
return event->PostDOMEvent();
}
NS_IMETHODIMP nsTreeSelection::GetCurrentColumn(nsITreeColumn** aCurrentColumn)
{
NS_IF_ADDREF(*aCurrentColumn = mCurrentColumn);
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::SetCurrentColumn(nsITreeColumn* aCurrentColumn)
{
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) \
{ \
nsTreeRange* macro_new_range = new nsTreeRange(macro_selection, (macro_start), (macro_end)); \

Просмотреть файл

@ -43,6 +43,7 @@
#define nsTreeSelection_h__
#include "nsITreeSelection.h"
#include "nsITreeColumns.h"
#include "nsITimer.h"
class nsITreeBoxObject;
@ -69,6 +70,7 @@ protected:
PRBool mSuppressed; // Whether or not we should be firing onselect events.
PRInt32 mCurrentIndex; // The item to draw the rect around. The last one clicked, etc.
nsCOMPtr<nsITreeColumn> mCurrentColumn;
PRInt32 mShiftSelectPivot; // Used when multiple SHIFT+selects are performed to pivot on.
nsTreeRange* mFirstRange; // Our list of ranges.

Просмотреть файл

@ -184,7 +184,7 @@
onclick="CycleFolderView(true);"/>
</sidebarheader>
<tree id="folderTree" class="plain focusring" flex="1" seltype="single" selstyle="primary"
<tree id="folderTree" class="plain focusring" flex="1" seltype="text"
context="folderPaneContext"
disableKeyNavigation="true"
datasources="rdf:null"
@ -288,17 +288,20 @@
<treecol id="folderUnreadCol"
persist="hidden width"
flex="1"
label="&unreadColumn.label;"/>
label="&unreadColumn.label;"
selectable="false"/>
<splitter class="tree-splitter"/>
<treecol id="folderTotalCol"
persist="hidden width"
flex="1"
label="&totalColumn.label;"/>
label="&totalColumn.label;"
selectable="false"/>
<splitter class="tree-splitter"/>
<treecol id="folderSizeCol"
persist="hidden width"
flex="1"
label="&folderSizeColumn.label;"/>
label="&folderSizeColumn.label;"
selectable="false"/>
</treecols>
</tree>
</vbox>

Просмотреть файл

@ -416,6 +416,7 @@ var gDownloadActionsWindow = {
selectionChanged: function () {},
cycleCell: function (aIndex, aColumn) {},
isEditable: function (aIndex, aColumn) { return false; },
isSelectable: function (aIndex, aColumn) { return false; },
setCellValue: function (aIndex, aColumn, aValue) {},
setCellText: function (aIndex, aColumn, aValue) {},
performAction: function (aAction) {},

Просмотреть файл

@ -333,6 +333,10 @@ var gFeedSubscriptionsWindow = {
{
return false;
},
isSelectable: function (aIndex, aColumn)
{
return false;
},
setCellValue: function (aIndex, aColumn, aValue) {},
setCellText: function (aIndex, aColumn, aValue) {},
performAction: function (aAction) {},

Просмотреть файл

@ -82,7 +82,8 @@ treechildren::-moz-tree-row(selected, current, focus) {
border: 1px dotted #C0C0C0;
}
tree[selstyle="primary"] > treechildren::-moz-tree-row {
tree[seltype="cell"] > treechildren::-moz-tree-row,
tree[seltype="text"] > treechildren::-moz-tree-row {
border: none;
background-color: transparent;
}
@ -93,7 +94,8 @@ treechildren::-moz-tree-cell {
padding: 0px 2px 0px 2px;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text,
tree[seltype="cell"] > treechildren::-moz-tree-cell-text,
tree[seltype="text"] > treechildren::-moz-tree-cell-text,
treechildren::-moz-tree-cell-text {
color: inherit;
}
@ -102,12 +104,24 @@ treechildren::-moz-tree-cell-text(selected) {
color: -moz-DialogText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary) {
tree[seltype="cell"] > treechildren::-moz-tree-cell {
border: 1px solid transparent;
padding: 0px 1px 0px 1px;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text {
border: 1px solid transparent;
padding: 0px 1px 1px 1px;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected) {
background-color: -moz-Dialog;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected) {
color: -moz-DialogText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected) {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
@ -116,27 +130,44 @@ treechildren::-moz-tree-cell-text(selected, focus) {
color: HighlightText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, focus) {
background-color: Highlight;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: HighlightText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
background-color: Highlight;
color: HighlightText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, current, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, current, focus) {
border: 1px dotted #000000;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected, current, focus) {
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, current, focus) {
border: 1px dotted #000000;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, current, focus) {
border: 1px dotted #C0C0C0;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, current, focus) {
border: 1px dotted #C0C0C0;
}
/* ::::: lines connecting cells ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-line,
tree[seltype="cell"] > treechildren::-moz-tree-line,
tree[seltype="text"] > treechildren::-moz-tree-line,
treechildren::-moz-tree-line {
border: 1px dotted ThreeDShadow;
}
tree[seltype="cell"] > treechildren::-moz-tree-line(active, selected, focus),
treechildren::-moz-tree-line(selected, focus) {
border: 1px dotted HighlightText;
}
@ -152,7 +183,8 @@ treechildren::-moz-tree-separator {
/* ::::: drop feedback ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell-text(primary, dropOn),
treechildren::-moz-tree-cell-text(primary, dropOn) {
background-color: Highlight;
color: HighlightText;

Просмотреть файл

@ -572,6 +572,11 @@ NS_IMETHODIMP nsAbView::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool* _ret
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsAbView::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool* _retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsAbView::SetCellValue(PRInt32 row, nsITreeColumn* col, const nsAString& value)
{
return NS_ERROR_NOT_IMPLEMENTED;

Просмотреть файл

@ -48,7 +48,7 @@
<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree id="folderTree" class="plain focusring" flex="1" seltype="single" selstyle="primary"
<tree id="folderTree" class="plain focusring" flex="1" seltype="text"
disableKeyNavigation="true"
datasources="rdf:null"
statedatasource="rdf:mailnewsfolders"
@ -157,19 +157,22 @@
hidden="true"
persist="hidden width"
flex="1"
label="&unreadColumn.label;"/>
label="&unreadColumn.label;"
selectable="false"/>
<splitter class="tree-splitter"/>
<treecol id="folderTotalCol"
hidden="true"
persist="hidden width"
flex="1"
label="&totalColumn.label;"/>
label="&totalColumn.label;"
selectable="false"/>
<splitter class="tree-splitter"/>
<treecol id="folderSizeCol"
hidden="true"
persist="hidden width"
flex="1"
label="&folderSizeColumn.label;"/>
label="&folderSizeColumn.label;"
selectable="false"/>
</treecols>
</tree>
</overlay>

Просмотреть файл

@ -1835,6 +1835,10 @@
<body>
<![CDATA[
var view = this.tree.view;
if (!view.selection.currentColumn)
view.selection.currentColumn = this.tree.columns.getFirstColumn();
view.selection.selectEventsSuppressed = true;
for (var i = 0; i < view.rowCount; i++) {
if (view.isContainer(i)) {
@ -1900,7 +1904,7 @@
<binding id="folderTargetPopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
<tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" seltype="text" hidecolumnpicker="true">
<treecols>
<treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
</treecols>
@ -1943,7 +1947,7 @@
<binding id="locationpopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree class="foldersTree" flex="1" datasources="rdf:null" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
<tree class="foldersTree" flex="1" datasources="rdf:null" flags="dont-build-content" seltype="text" hidecolumnpicker="true">
<treecols>
<treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
</treecols>
@ -1966,7 +1970,7 @@
<binding id="searchpopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
<tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" seltype="text" hidecolumnpicker="true">
<treecols>
<treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
</treecols>

Просмотреть файл

@ -939,6 +939,12 @@ NS_IMETHODIMP nsMsgDBView::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool* _
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool* _retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::SetCellValue(PRInt32 row, nsITreeColumn* col, const nsAString& value)
{
return NS_OK;

Просмотреть файл

@ -2033,6 +2033,13 @@ nsNntpIncomingServer::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool *_retva
return NS_OK;
}
NS_IMETHODIMP
nsNntpIncomingServer::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsNntpIncomingServer::SetCellValue(PRInt32 row, nsITreeColumn* col, const nsAString& value)
{

Просмотреть файл

@ -401,6 +401,15 @@ nsNSSASN1Tree::IsEditable(PRInt32 row, nsITreeColumn* col,
return NS_OK;
}
/* boolean isSelectable (in long row, in nsITreeColumn col); */
NS_IMETHODIMP
nsNSSASN1Tree::IsSelectable(PRInt32 row, nsITreeColumn* col,
PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
/* void setCellValue (in long row, in nsITreeColumn col, in AString value); */
NS_IMETHODIMP
nsNSSASN1Tree::SetCellValue(PRInt32 row, nsITreeColumn* col,

Просмотреть файл

@ -906,6 +906,14 @@ nsCertTree::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
return NS_OK;
}
/* boolean isSelectable (in long row, in nsITreeColumn col); */
NS_IMETHODIMP
nsCertTree::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
/* void setCellValue (in long row, in nsITreeColumn col, in AString value); */
NS_IMETHODIMP
nsCertTree::SetCellValue(PRInt32 row, nsITreeColumn* col,

Просмотреть файл

@ -84,7 +84,8 @@ treechildren::-moz-tree-row(selected, focus) {
background-color: Highlight;
}
tree[selstyle="primary"] > treechildren::-moz-tree-row {
tree[seltype="cell"] > treechildren::-moz-tree-row,
tree[seltype="text"] > treechildren::-moz-tree-row {
border-top: none;
background-color: transparent;
}
@ -95,12 +96,17 @@ treechildren::-moz-tree-cell {
padding: 0px 2px 0px 2px;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text,
tree[seltype="cell"] > treechildren::-moz-tree-cell-text,
tree[seltype="text"] > treechildren::-moz-tree-cell-text,
treechildren::-moz-tree-cell-text {
color: inherit;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary) {
tree[seltype="cell"] > treechildren::-moz-tree-cell {
padding: 0px 1px 0px 1px;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text {
padding: 0px 1px 1px 1px;
}
@ -108,7 +114,14 @@ treechildren::-moz-tree-cell-text(selected) {
color: -moz-DialogText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected) {
background-color: -moz-Dialog;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected) {
color: -moz-DialogText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected) {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
@ -117,7 +130,14 @@ treechildren::-moz-tree-cell-text(selected, focus) {
color: HighlightText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, focus) {
background-color: Highlight;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: HighlightText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
background-color: Highlight;
color: HighlightText;
}
@ -148,7 +168,8 @@ treechildren::-moz-tree-separator {
/* ::::: drop feedback ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell-text(primary, dropOn),
treechildren::-moz-tree-cell-text(primary, dropOn) {
background-color: Highlight;
color: HighlightText;

Просмотреть файл

@ -92,7 +92,8 @@ treechildren::-moz-tree-row(selected, current, focus) {
border: 1px dotted #C0C0C0;
}
tree[selstyle="primary"] > treechildren::-moz-tree-row {
tree[seltype="cell"] > treechildren::-moz-tree-row,
tree[seltype="text"] > treechildren::-moz-tree-row {
border: none;
background-color: transparent;
}
@ -103,7 +104,8 @@ treechildren::-moz-tree-cell {
padding: 0px 2px 0px 2px;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text,
tree[seltype="cell"] > treechildren::-moz-tree-cell-text,
tree[seltype="text"] > treechildren::-moz-tree-cell-text,
treechildren::-moz-tree-cell-text {
color: inherit;
}
@ -112,12 +114,24 @@ treechildren::-moz-tree-cell-text(selected) {
color: -moz-cellhighlighttext;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary) {
tree[seltype="cell"] > treechildren::-moz-tree-cell {
border: 1px solid transparent;
padding: 0px 1px 0px 1px;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text {
border: 1px solid transparent;
padding: 0px 1px 1px 1px;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected) {
background-color: -moz-cellhighlight;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected) {
color: -moz-cellhighlighttext;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected) {
background-color: -moz-cellhighlight;
color: -moz-cellhighlighttext;
}
@ -126,27 +140,43 @@ treechildren::-moz-tree-cell-text(selected, focus) {
color: HighlightText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, focus) {
background-color: Highlight;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: HighlightText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
background-color: Highlight;
color: HighlightText;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, current, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, current, focus) {
border: 1px dotted #000000;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected, current, focus) {
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, current, focus) {
border: 1px dotted #000000;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, current, focus) {
border: 1px dotted #C0C0C0;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, current, focus) {
border: 1px dotted #C0C0C0;
}
/* ::::: lines connecting cells ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-line,
tree[seltype="cell"] > treechildren::-moz-tree-line,
tree[seltype="text"] > treechildren::-moz-tree-line,
treechildren::-moz-tree-line {
border: 1px dotted ThreeDShadow;
}
tree[seltype="cell"] > treechildren::-moz-tree-line(active, selected, focus),
treechildren::-moz-tree-line(selected, focus) {
border: 1px dotted HighlightText;
}
@ -166,7 +196,8 @@ treechildren::-moz-tree-separator {
/* ::::: drop feedback ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell-text(primary, dropOn),
treechildren::-moz-tree-cell-text(primary, dropOn) {
background-color: Highlight;
color: HighlightText;

Просмотреть файл

@ -93,7 +93,8 @@ treechildren::-moz-tree-row(current, focus) {
border-bottom-color: #000000;
}
tree[selstyle="primary"] > treechildren::-moz-tree-row {
tree[seltype="cell"] > treechildren::-moz-tree-row,
tree[seltype="text"] > treechildren::-moz-tree-row {
background-color: transparent;
border: none;
}
@ -104,12 +105,18 @@ treechildren::-moz-tree-cell {
padding: 0px 2px 0px 2px;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text,
tree[seltype="cell"] > treechildren::-moz-tree-cell-text,
tree[seltype="text"] > treechildren::-moz-tree-cell-text,
treechildren::-moz-tree-cell-text {
color: inherit;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary) {
tree[seltype="cell"] > treechildren::-moz-tree-cell {
border: 1px solid transparent;
padding: 0px 1px 0px 1px;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text {
border: 1px solid transparent;
padding: 0px 1px 1px 1px;
}
@ -118,7 +125,12 @@ treechildren::-moz-tree-cell-text(selected) {
color: #000000;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected) {
background-color: #C7D0D9;
color: #000000;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected) {
background-color: #C7D0D9;
color: #000000;
}
@ -127,22 +139,35 @@ treechildren::-moz-tree-cell-text(selected, focus) {
color: #FFFFFF;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, selected, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, focus) {
background-color: #424F63;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: #FFFFFF;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
background-color: #424F63;
color: #FFFFFF;
}
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, current, focus) {
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, current, focus) {
border-color: #000000;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, current, focus) {
border-color: #000000;
}
/* ::::: lines connecting cells ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-line,
tree[seltype="cell"] > treechildren::-moz-tree-line,
tree[seltype="text"] > treechildren::-moz-tree-line,
treechildren::-moz-tree-line {
border: 1px dotted #808080;
}
tree[seltype="cell"] > treechildren::-moz-tree-line(active, selected, focus),
treechildren::-moz-tree-line(selected, focus) {
border: 1px dotted #FFFFFF;
}
@ -158,7 +183,8 @@ treechildren::-moz-tree-separator {
/* ::::: drop feedback ::::: */
tree[selstyle="primary"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell-text(primary, dropOn),
treechildren::-moz-tree-cell-text(primary, dropOn) {
background-color: #424F63;
color: #FFFFFF;

Просмотреть файл

@ -860,6 +860,13 @@ nsAutoCompleteController::IsEditable(PRInt32 row, nsITreeColumn* col, PRBool *_r
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteController::IsSelectable(PRInt32 row, nsITreeColumn* col, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteController::IsSeparator(PRInt32 index, PRBool *_retval)
{

Просмотреть файл

@ -156,6 +156,7 @@ var view = {
selectionChanged : function() {},
cycleCell: function(row, col) {},
isEditable: function(row, col) {return false; },
isSelectable: function(row, col) {return false; },
setCellValue: function(row, col, value) {},
setCellText: function(row, col, value) {},
performAction: function(action) {},

Просмотреть файл

@ -107,7 +107,7 @@
onget="return this.hasAttribute('disableKeyNavigation');"
onset="if (val) this.setAttribute('disableKeyNavigation', 'true');
else this.removeAttribute('disableKeyNavigation'); return val;"/>
<property name="_selectDelay"
onset="this.setAttribute('_selectDelay', val);"
onget="return this.getAttribute('_selectDelay') || 50;"/>
@ -223,6 +223,35 @@
]]></body>
</method>
<property name="_cellSelType">
<getter>
<![CDATA[
var seltype = this.selType;
if (seltype == "cell" || seltype == "text")
return seltype;
return null;
]]>
</getter>
</property>
<method name="_getNextColumn">
<parameter name="row"/>
<parameter name="left"/>
<body><![CDATA[
var col = this.view.selection.currentColumn;
if (col) {
col = left ? col.getPrevious() : col.getNext();
}
else {
col = this.columns.getKeyColumn();
}
while (col && (col.width == 0 || !col.selectable ||
!this.view.isSelectable(row, col)))
col = left ? col.getPrevious() : col.getNext();
return col;
]]></body>
</method>
</implementation>
<handlers>
@ -243,6 +272,10 @@
if (this.currentIndex == -1 && this.view.rowCount > 0) {
this.currentIndex = this.treeBoxObject.getFirstVisibleRow();
}
if (this._cellSelType && !this.view.selection.currentColumn) {
var col = this._getNextColumn(this.currentIndex, false);
this.view.selection.currentColumn = col;
}
]]>
</handler>
<handler event="blur" action="this.treeBoxObject.focused = false;"/>
@ -250,11 +283,41 @@
<handler event="keypress" keycode="vk_return" action="this.changeOpenState(this.currentIndex);"/>
<handler event="keypress" keycode="vk_left">
<![CDATA[
if (!this.changeOpenState(this.currentIndex, false)) {
var parentIndex = this.view.getParentIndex(this.currentIndex);
if (parentIndex >= 0) {
this.view.selection.select(parentIndex);
this.treeBoxObject.ensureRowIsVisible(parentIndex);
var row = this.currentIndex;
if (row < 0)
return;
var cellSelType = this._cellSelType;
var checkContainers = true;
var currentColumn;
if (cellSelType) {
currentColumn = this.view.selection.currentColumn;
if (currentColumn && !currentColumn.primary)
checkContainers = false;
}
if (checkContainers) {
if (this.changeOpenState(this.currentIndex, false))
return;
else {
var parentIndex = this.view.getParentIndex(this.currentIndex);
if (parentIndex >= 0) {
if (cellSelType && !this.view.isSelectable(parentIndex, currentColumn)) {
return;
}
this.view.selection.select(parentIndex);
this.treeBoxObject.ensureRowIsVisible(parentIndex);
return;
}
}
}
if (cellSelType) {
var col = this._getNextColumn(row, true);
if (col) {
this.view.selection.currentColumn = col;
this.treeBoxObject.ensureCellIsVisible(row, col);
}
}
]]>
@ -262,15 +325,48 @@
<handler event="keypress" keycode="vk_right">
<![CDATA[
var row = this.currentIndex;
if (row >= 0 && !this.changeOpenState(row, true)) {
var view = this.view;
if (row + 1 < view.rowCount &&
view.getParentIndex(row + 1) == row) {
// If already opened, select the first child.
// The getParentIndex test above ensures that the children
// are already populated and ready.
this.view.selection.timedSelect(row + 1, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(row + 1);
if (row < 0)
return;
var cellSelType = this._cellSelType;
var checkContainers = true;
var currentColumn;
if (cellSelType) {
currentColumn = this.view.selection.currentColumn;
if (currentColumn && !currentColumn.primary)
checkContainers = false;
}
if (checkContainers) {
if (this.changeOpenState(row, true))
return;
else {
var c = row + 1;
var view = this.view;
if (c < view.rowCount &&
view.getParentIndex(c) == row) {
// If already opened, select the first child.
// The getParentIndex test above ensures that the children
// are already populated and ready.
if (cellSelType && !this.view.isSelectable(c , currentColumn)) {
var col = this._getNextColumn(c, false);
if (col) {
this.view.selection.currentColumn = col;
}
}
this.view.selection.timedSelect(c, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(c);
return;
}
}
}
if (cellSelType) {
var col = this._getNextColumn(row, false);
if (col) {
this.view.selection.currentColumn = col;
this.treeBoxObject.ensureCellIsVisible(row, col);
}
}
]]>
@ -282,14 +378,27 @@
return;
}
var c = this.currentIndex;
if (c == -1 || c == 0)
var c = this.currentIndex - 1;
if (c < 0)
return;
var cellSelType = this._cellSelType;
if (cellSelType) {
var column = this.view.selection.currentColumn;
if (!column)
return;
while (c >= 0 && !this.view.isSelectable(c, column))
c--;
if (c < 0)
return;
}
if (!this._isAccelPressed(event))
this.view.selection.timedSelect(c - 1, this._selectDelay);
this.view.selection.timedSelect(c, this._selectDelay);
else // Ctrl+Up moves the anchor without selecting
this.currentIndex = c - 1;
this.treeBoxObject.ensureRowIsVisible(c-1);
this.currentIndex = c;
this.treeBoxObject.ensureRowIsVisible(c);
]]>
</handler>
<handler event="keypress" keycode="vk_down" modifiers="accel any">
@ -298,16 +407,28 @@
this.treeBoxObject.scrollByLines(1);
return;
}
var c = this.currentIndex;
try {
if (c+1 == this.view.rowCount)
return;
} catch (e) {}
var c = this.currentIndex + 1;
if (c == this.view.rowCount)
return;
var cellSelType = this._cellSelType;
if (cellSelType) {
var column = this.view.selection.currentColumn;
if (!column)
return;
while (c < this.view.rowCount && !this.view.isSelectable(c, column))
c++;
if (c == this.view.rowCount)
return;
}
if (!this._isAccelPressed(event))
this.view.selection.timedSelect(c+1, this._selectDelay);
this.view.selection.timedSelect(c, this._selectDelay);
else // Ctrl+Down moves the anchor without selecting
this.currentIndex = c + 1;
this.treeBoxObject.ensureRowIsVisible(c+1);
this.currentIndex = c;
this.treeBoxObject.ensureRowIsVisible(c);
]]>
</handler>
<handler event="keypress" keycode="vk_up" modifiers="accel any, shift">
@ -328,10 +449,8 @@
if (this.view.selection.single)
return;
var c = this.currentIndex;
try {
if (c+1 == this.view.rowCount)
return;
} catch (e) {}
if (c+1 == this.view.rowCount)
return;
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, c + 1,
this._isAccelPressed(event));
@ -637,10 +756,25 @@
}
}
var cellSelType = this.parentNode._cellSelType;
if (cellSelType == "text" && obj.value != "text" && obj.value != "image")
return;
if (cellSelType) {
if (!col.value.selectable ||
!b.view.isSelectable(row.value, col.value)) {
return;
}
}
if (!b.view.selection.isSelected(row.value)) {
b.view.selection.select(row.value);
b.ensureRowIsVisible(row.value);
}
if (cellSelType) {
b.view.selection.currentColumn = col.value;
}
}
]]>
</handler>
@ -666,8 +800,16 @@
var parentIndex = b.view.getParentIndex(b.view.selection.currentIndex);
while (parentIndex >= 0 && parentIndex != row.value)
parentIndex = b.view.getParentIndex(parentIndex);
if (parentIndex == row.value)
b.view.selection.select(parentIndex);
if (parentIndex == row.value) {
var parentSelectable = true;
if (this.parentNode._cellSelType) {
var currentColumn = b.view.selection.currentColumn;
if (!b.view.isSelectable(parentIndex, currentColumn))
parentSelectable = false;
}
if (parentSelectable)
b.view.selection.select(parentIndex);
}
}
this.parentNode.changeOpenState(row.value);
return;
@ -700,8 +842,24 @@
// see bug #92366
if (!col.value.cycler && this._lastSelectedRow == row.value &&
col.value.type != Components.interfaces.nsITreeColumn.TYPE_CHECKBOX) {
var cellSelType = this.parentNode._cellSelType;
if (cellSelType == "text" && obj.value != "text" && obj.value != "image")
return;
if (cellSelType) {
if (!col.value.selectable ||
!b.view.isSelectable(row.value, col.value)) {
return;
}
}
b.view.selection.select(row.value);
b.ensureRowIsVisible(row.value);
if (cellSelType) {
b.view.selection.currentColumn = col.value;
}
}
]]>
</handler>

Просмотреть файл

@ -92,25 +92,65 @@ tree:not([hidecolumnpicker="true"]) treechildren::-moz-tree-row(odd, selected, f
color: #FFFFFF;
}
tree[seltype="cell"] > treechildren::-moz-tree-row,
tree[seltype="text"] > treechildren::-moz-tree-row {
border-top: none;
background-color: transparent;
}
/* ::::: tree cells ::::: */
treechildren::-moz-tree-cell {
padding: 0px 2px 0px 2px;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text,
tree[seltype="text"] > treechildren::-moz-tree-cell-text,
treechildren::-moz-tree-cell-text {
color: inherit;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell {
padding: 0px 1px 0px 1px;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text {
padding: 0px 1px 1px 1px;
}
treechildren::-moz-tree-cell-text(selected) {
color: -moz-DialogText;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected) {
background-color: #D0D0D0;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected) {
color: -moz-DialogText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected) {
background-color: #D0D0D0;
color: -moz-DialogText;
}
treechildren::-moz-tree-cell-text(selected, focus) {
/* color: HighlightText; */
color: #FFFFFF;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, focus) {
background-color: #3874D1;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: #FFFFFF;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
background-color: #3874D1;
color: #FFFFFF;
}
/* ::::: lines connecting cells ::::: */
@ -133,11 +173,15 @@ treechildren::-moz-tree-separator {
/* ::::: drop feedback ::::: */
tree[seltype="cell"] > treechildren::-moz-tree-cell(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell(primary, dropOn),
treechildren::-moz-tree-cell(primary, dropOn) {
background-color: #A1A1A1 !important;
color: #FFF !important;
background-image: none;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell-text(primary, dropOn),
treechildren::-moz-tree-cell-text(primary, dropOn) {
color: #FFF !important;
}

Просмотреть файл

@ -91,12 +91,20 @@ treechildren::-moz-tree-row(selected, current, focus) {
border: 1px dotted #F3D982;
}
tree[seltype="cell"] > treechildren::-moz-tree-row,
tree[seltype="text"] > treechildren::-moz-tree-row {
border: none;
background-color: transparent;
}
/* ::::: tree cells ::::: */
treechildren::-moz-tree-cell {
padding: 0px 2px 0px 2px;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text,
tree[seltype="text"] > treechildren::-moz-tree-cell-text,
treechildren::-moz-tree-cell-text {
color: inherit;
}
@ -105,17 +113,73 @@ treechildren::-moz-tree-cell-text(selected) {
color: -moz-DialogText;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell {
border: 1px solid transparent;
padding: 0px 1px 0px 1px;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text {
border: 1px solid transparent;
padding: 0px 1px 1px 1px;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected) {
background-color: -moz-Dialog;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected) {
color: -moz-DialogText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected) {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
treechildren::-moz-tree-cell-text(selected, focus) {
color: HighlightText;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, focus) {
background-color: Highlight;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
background-color: Highlight;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: HighlightText;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, focus) {
color: HighlightText;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, current, focus) {
border: 1px dotted #000000;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, current, focus) {
border: 1px dotted #000000;
}
tree[seltype="cell"] > treechildren::-moz-tree-cell(active, selected, current, focus) {
border: 1px dotted #C0C0C0;
}
tree[seltype="text"] > treechildren::-moz-tree-cell-text(active, selected, current, focus) {
border: 1px dotted #C0C0C0;
}
/* ::::: lines connecting cells ::::: */
tree[seltype="cell"] > treechildren::-moz-tree-line,
tree[seltype="text"] > treechildren::-moz-tree-line,
treechildren::-moz-tree-line {
border: 1px dotted ThreeDShadow;
}
tree[seltype="cell"] > treechildren::-moz-tree-line(active, selected, focus),
treechildren::-moz-tree-line(selected, focus) {
border: 1px dotted HighlightText;
}
@ -131,6 +195,8 @@ treechildren::-moz-tree-separator {
/* ::::: drop feedback ::::: */
tree[seltype="cell"] > treechildren::-moz-tree-cell-text(primary, dropOn),
tree[seltype="text"] > treechildren::-moz-tree-cell-text(primary, dropOn),
treechildren::-moz-tree-cell-text(primary, dropOn) {
background-color: Highlight;
color: HighlightText;

Просмотреть файл

@ -150,6 +150,7 @@ pageInfoTreeView.prototype = {
selectionChanged: function() { },
cycleCell: function(row, column) { },
isEditable: function(row, column) { return false; },
isSelectable: function(row, column) { return false; },
performAction: function(action) { },
performActionOnCell: function(action, row, column) { }
};

Просмотреть файл

@ -1425,6 +1425,7 @@
cycleHeader: function(aCol) {},
cycleCell: function(aRow, aCol) {},
isEditable: function(aRow, aCol) {},
isSelectable: function(aRow, aCol) {},
setCellValue: function(aRow, aCol, aValue) {},
setCellText: function(aRow, aCol, aValue) {},
performAction: function(aAction) {},

Просмотреть файл

@ -769,6 +769,14 @@ nsFileView::IsEditable(PRInt32 aRow, nsITreeColumn* aCol,
return NS_OK;
}
NS_IMETHODIMP
nsFileView::IsSelectable(PRInt32 aRow, nsITreeColumn* aCol,
PRBool* aIsSelectable)
{
*aIsSelectable = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsFileView::SetCellValue(PRInt32 aRow, nsITreeColumn* aCol,
const nsAString& aValue)

Просмотреть файл

@ -90,7 +90,7 @@
onget="return this.hasAttribute('disableKeyNavigation');"
onset="if (val) this.setAttribute('disableKeyNavigation', 'true');
else this.removeAttribute('disableKeyNavigation'); return val;"/>
<property name="_selectDelay"
onset="this.setAttribute('_selectDelay', val);"
onget="return this.getAttribute('_selectDelay') || 50;"/>
@ -206,6 +206,35 @@
]]></body>
</method>
<property name="_cellSelType">
<getter>
<![CDATA[
var seltype = this.selType;
if (seltype == "cell" || seltype == "text")
return seltype;
return null;
]]>
</getter>
</property>
<method name="_getNextColumn">
<parameter name="row"/>
<parameter name="left"/>
<body><![CDATA[
var col = this.view.selection.currentColumn;
if (col) {
col = left ? col.getPrevious() : col.getNext();
}
else {
col = this.columns.getKeyColumn();
}
while (col && (col.width == 0 || !col.selectable ||
!this.view.isSelectable(row, col)))
col = left ? col.getPrevious() : col.getNext();
return col;
]]></body>
</method>
</implementation>
<handlers>
@ -226,11 +255,41 @@
<handler event="keypress" keycode="vk_return" action="this.changeOpenState(this.currentIndex);"/>
<handler event="keypress" keycode="vk_left">
<![CDATA[
if (!this.changeOpenState(this.currentIndex, false)) {
var parentIndex = this.view.getParentIndex(this.currentIndex);
if (parentIndex >= 0) {
this.view.selection.select(parentIndex);
this.treeBoxObject.ensureRowIsVisible(parentIndex);
var row = this.currentIndex;
if (row < 0)
return;
var cellSelType = this._cellSelType;
var checkContainers = true;
var currentColumn;
if (cellSelType) {
currentColumn = this.view.selection.currentColumn;
if (currentColumn && !currentColumn.primary)
checkContainers = false;
}
if (checkContainers) {
if (this.changeOpenState(this.currentIndex, false))
return;
else {
var parentIndex = this.view.getParentIndex(this.currentIndex);
if (parentIndex >= 0) {
if (cellSelType && !this.view.isSelectable(parentIndex, currentColumn)) {
return;
}
this.view.selection.select(parentIndex);
this.treeBoxObject.ensureRowIsVisible(parentIndex);
return;
}
}
}
if (cellSelType) {
var col = this._getNextColumn(row, true);
if (col) {
this.view.selection.currentColumn = col;
this.treeBoxObject.ensureCellIsVisible(row, col);
}
}
]]>
@ -238,15 +297,48 @@
<handler event="keypress" keycode="vk_right">
<![CDATA[
var row = this.currentIndex;
if (row >= 0 && !this.changeOpenState(row, true)) {
var view = this.view;
if (row + 1 < view.rowCount &&
view.getParentIndex(row + 1) == row) {
// If already opened, select the first child.
// The getParentIndex test above ensures that the children
// are already populated and ready.
this.view.selection.timedSelect(row + 1, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(row + 1);
if (row < 0)
return;
var cellSelType = this._cellSelType;
var checkContainers = true;
var currentColumn;
if (cellSelType) {
currentColumn = this.view.selection.currentColumn;
if (currentColumn && !currentColumn.primary)
checkContainers = false;
}
if (checkContainers) {
if (this.changeOpenState(row, true))
return;
else {
var c = row + 1;
var view = this.view;
if (c < view.rowCount &&
view.getParentIndex(c) == row) {
// If already opened, select the first child.
// The getParentIndex test above ensures that the children
// are already populated and ready.
if (cellSelType && !this.view.isSelectable(c , currentColumn)) {
var col = this._getNextColumn(c, false);
if (col) {
this.view.selection.currentColumn = col;
}
}
this.view.selection.timedSelect(c, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(c);
return;
}
}
}
if (cellSelType) {
var col = this._getNextColumn(row, false);
if (col) {
this.view.selection.currentColumn = col;
this.treeBoxObject.ensureCellIsVisible(row, col);
}
}
]]>
@ -258,14 +350,27 @@
return;
}
var c = this.currentIndex;
if (c == -1 || c == 0)
var c = this.currentIndex - 1;
if (c < 0)
return;
var cellSelType = this._cellSelType;
if (cellSelType) {
var column = this.view.selection.currentColumn;
if (!column)
return;
while (c >= 0 && !this.view.isSelectable(c, column))
c--;
if (c < 0)
return;
}
if (!event.ctrlKey)
this.view.selection.timedSelect(c - 1, this._selectDelay);
this.view.selection.timedSelect(c, this._selectDelay);
else // Ctrl+Up moves the anchor without selecting
this.currentIndex = c - 1;
this.treeBoxObject.ensureRowIsVisible(c-1);
this.currentIndex = c;
this.treeBoxObject.ensureRowIsVisible(c);
]]>
</handler>
<handler event="keypress" keycode="vk_down" modifiers="control any">
@ -274,16 +379,28 @@
this.treeBoxObject.scrollByLines(1);
return;
}
var c = this.currentIndex;
try {
if (c+1 == this.view.rowCount)
return;
} catch (e) {}
var c = this.currentIndex + 1;
if (c == this.view.rowCount)
return;
var cellSelType = this._cellSelType;
if (cellSelType) {
var column = this.view.selection.currentColumn;
if (!column)
return;
while (c < this.view.rowCount && !this.view.isSelectable(c, column))
c++;
if (c == this.view.rowCount)
return;
}
if (!event.ctrlKey)
this.view.selection.timedSelect(c+1, this._selectDelay);
this.view.selection.timedSelect(c, this._selectDelay);
else // Ctrl+Down moves the anchor without selecting
this.currentIndex = c + 1;
this.treeBoxObject.ensureRowIsVisible(c+1);
this.currentIndex = c;
this.treeBoxObject.ensureRowIsVisible(c);
]]>
</handler>
<handler event="keypress" keycode="vk_up" modifiers="control any, shift">
@ -303,10 +420,8 @@
if (this.view.selection.single)
return;
var c = this.currentIndex;
try {
if (c+1 == this.view.rowCount)
return;
} catch (e) {}
if (c+1 == this.view.rowCount)
return;
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, c + 1, event.ctrlKey);
this.treeBoxObject.ensureRowIsVisible(c + 1);
@ -608,10 +723,25 @@
}
}
var cellSelType = this.parentNode._cellSelType;
if (cellSelType == "text" && obj.value != "text" && obj.value != "image")
return;
if (cellSelType) {
if (!col.value.selectable ||
!b.view.isSelectable(row.value, col.value)) {
return;
}
}
if (!b.view.selection.isSelected(row.value)) {
b.view.selection.select(row.value);
b.ensureRowIsVisible(row.value);
}
if (cellSelType) {
b.view.selection.currentColumn = col.value;
}
}
]]>
</handler>
@ -637,8 +767,16 @@
var parentIndex = b.view.getParentIndex(b.view.selection.currentIndex);
while (parentIndex >= 0 && parentIndex != row.value)
parentIndex = b.view.getParentIndex(parentIndex);
if (parentIndex == row.value)
b.view.selection.select(parentIndex);
if (parentIndex == row.value) {
var parentSelectable = true;
if (this.parentNode._cellSelType) {
var currentColumn = b.view.selection.currentColumn;
if (!b.view.isSelectable(parentIndex, currentColumn))
parentSelectable = false;
}
if (parentSelectable)
b.view.selection.select(parentIndex);
}
}
this.parentNode.changeOpenState(row.value);
return;
@ -671,8 +809,24 @@
// see bug #92366
if (!col.value.cycler && this._lastSelectedRow == row.value &&
col.value.type != Components.interfaces.nsITreeColumn.TYPE_CHECKBOX) {
var cellSelType = this.parentNode._cellSelType;
if (cellSelType == "text" && obj.value != "text" && obj.value != "image")
return;
if (cellSelType) {
if (!col.value.selectable ||
!b.view.isSelectable(row.value, col.value)) {
return;
}
}
b.view.selection.select(row.value);
b.ensureRowIsVisible(row.value);
if (cellSelType) {
b.view.selection.currentColumn = col.value;
}
}
]]>
</handler>

Просмотреть файл

@ -157,6 +157,7 @@ var view = {
selectionChanged : function() {},
cycleCell: function(row, col) {},
isEditable: function(row, col) {return false; },
isSelectable: function(row, col) {return false; },
setCellValue: function(row, col, value) {},
setCellText: function(row, col, value) {},
performAction: function(action) {},