9656 - outliner column drag and drop rearranging, r=sspitzer, sr=hyatt

This commit is contained in:
hewitt%netscape.com 2001-09-25 22:17:47 +00:00
parent 433ff11b78
commit 989692bdd6
14 changed files with 613 additions and 99 deletions

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Ben Goodger <ben@netscape.com>
* Joe Hewitt <hewitt@netscape.com>
*/
#include "nsCOMPtr.h"
@ -253,6 +254,7 @@ nsOutlinerBodyFrame::nsOutlinerBodyFrame(nsIPresShell* aPresShell)
mAlreadyUndrewDueToScroll(PR_FALSE)
{
NS_NewISupportsArray(getter_AddRefs(mScratchArray));
mColumnsDirty = PR_TRUE;
}
// Destructor
@ -1037,8 +1039,6 @@ nsOutlinerBodyFrame::GetCoordsForCellItem(PRInt32 aRow, const PRUnichar *aColID,
return NS_OK;
}
nsresult
nsOutlinerBodyFrame::GetItemWithinCellAt(PRInt32 aX, const nsRect& aCellRect,
PRInt32 aRowIndex,
@ -1569,6 +1569,16 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintColumn(nsOutlinerColumn* aColumn,
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(aColumn->GetElement()));
mView->GetColumnProperties(aColumn->GetID(), elt, mScratchArray);
// Read special properties from attributes on the column content node
nsAutoString attr;
aColumn->GetElement()->GetAttr(kNameSpaceID_None, nsXULAtoms::insertbefore, attr);
if (attr.EqualsWithConversion("true"))
mScratchArray->AppendElement(nsXULAtoms::insertbefore);
attr.AssignWithConversion("");
aColumn->GetElement()->GetAttr(kNameSpaceID_None, nsXULAtoms::insertafter, attr);
if (attr.EqualsWithConversion("true"))
mScratchArray->AppendElement(nsXULAtoms::insertafter);
// Resolve style for the column. It contains all the info we need to lay ourselves
// out and to paint.
nsCOMPtr<nsIStyleContext> colContext;
@ -2327,10 +2337,19 @@ nsOutlinerBodyFrame::PseudoMatches(nsIAtom* aTag, nsCSSSelector* aSelector, PRBo
return NS_OK;
}
void
nsOutlinerBodyFrame::InvalidateColumnCache()
{
mColumnsDirty = PR_TRUE;
}
void
nsOutlinerBodyFrame::EnsureColumns()
{
if (!mColumns) {
if (!mColumns || mColumnsDirty) {
delete mColumns;
mColumnsDirty = PR_FALSE;
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
@ -2354,7 +2373,7 @@ nsOutlinerBodyFrame::EnsureColumns()
nsCOMPtr<nsIDOMNode> node;
cols->Item(0, getter_AddRefs(node));
nsCOMPtr<nsIContent> child(do_QueryInterface(node));
// Get the frame for this column.
nsIFrame* frame;
shell->GetPrimaryFrameFor(child, &frame);
@ -2365,26 +2384,28 @@ nsOutlinerBodyFrame::EnsureColumns()
frame->GetParent(&colContainer);
nsCOMPtr<nsIBox> colContainerBox(do_QueryInterface(colContainer));
PRBool isNormal = PR_TRUE;
colContainerBox->GetDirection(isNormal);
PRInt32 i = isNormal ? 0 : count-1;
nsIBox* colBox;
colContainerBox->GetChildBox(&colBox);
nsOutlinerColumn* currCol = nsnull;
for ( ; (isNormal ? (i < ((PRInt32)count)) : (i >= 0)); (isNormal ? i++ : i--)) {
nsCOMPtr<nsIDOMNode> node;
cols->Item(i, getter_AddRefs(node));
nsCOMPtr<nsIContent> child(do_QueryInterface(node));
// Get the frame for this column.
while (colBox) {
nsIFrame* frame;
shell->GetPrimaryFrameFor(child, &frame);
colBox->GetFrame(&frame);
nsCOMPtr<nsIContent> content;
frame->GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDOMElement> colElt(do_QueryInterface(content));
nsCOMPtr<nsIDOMNode> colParentElt;
colElt->GetParentNode(getter_AddRefs(colParentElt));
if (colParentElt == elt) {
// Create a new column structure.
nsOutlinerColumn* col = new nsOutlinerColumn(content, frame);
if (currCol)
currCol->SetNext(col);
else mColumns = col;
currCol = col;
}
// Create a new column structure.
nsOutlinerColumn* col = new nsOutlinerColumn(child, frame);
if (currCol)
currCol->SetNext(col);
else mColumns = col;
currCol = col;
colBox->GetNextBox(&colBox);
}
}
}

View File

@ -299,6 +299,10 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aRect, const nsRect& aDirtyRect);
// This method is called whenever an outlinercol is added or removed and
// the column cache needs to be rebuilt.
void InvalidateColumnCache();
friend nsresult NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame);
@ -402,6 +406,9 @@ protected: // Data Members
PRInt32 mRowHeight;
PRInt32 mIndentation;
// An indicator that columns have changed and need to be rebuilt
PRBool mColumnsDirty;
// A scratch array used when looking up cached style contexts.
nsCOMPtr<nsISupportsArray> mScratchArray;

View File

@ -33,6 +33,7 @@
#include "nsIDocument.h"
#include "nsIBoxObject.h"
#include "nsIDOMElement.h"
#include "nsOutlinerBodyFrame.h"
//
// NS_NewOutlinerColFrame
@ -84,6 +85,18 @@ nsOutlinerColFrame::~nsOutlinerColFrame()
{
}
NS_IMETHODIMP
nsOutlinerColFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
InvalidateColumnCache(aPresContext);
return rv;
}
NS_IMETHODIMP
nsOutlinerColFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
@ -162,24 +175,52 @@ nsOutlinerColFrame::AttributeChanged(nsIPresContext* aPresContext,
if (aAttribute == nsHTMLAtoms::width || aAttribute == nsHTMLAtoms::hidden) {
// Invalidate the outliner.
if (!mOutliner) {
// Get our parent node.
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
nsCOMPtr<nsIBoxObject> boxObject;
nsDoc->GetBoxObjectFor(elt, getter_AddRefs(boxObject));
mOutliner = do_QueryInterface(boxObject);
}
EnsureOutliner();
if (mOutliner)
mOutliner->Invalidate();
} else if (aAttribute == nsXULAtoms::ordinal) {
InvalidateColumnCache(aPresContext);
}
return rv;
}
void
nsOutlinerColFrame::EnsureOutliner()
{
if (!mOutliner && mContent) {
// Get our parent node.
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
nsCOMPtr<nsIBoxObject> boxObject;
nsDoc->GetBoxObjectFor(elt, getter_AddRefs(boxObject));
mOutliner = do_QueryInterface(boxObject);
}
}
void
nsOutlinerColFrame::InvalidateColumnCache(nsIPresContext* aPresContext)
{
EnsureOutliner();
if (mOutliner) {
nsCOMPtr<nsIDOMElement> bodyEl;
mOutliner->GetOutlinerBody(getter_AddRefs(bodyEl));
nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(bodyEl);
if (bodyContent) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsIFrame* frame;
shell->GetPrimaryFrameFor(bodyContent, &frame);
if (frame) {
nsOutlinerBodyFrame* oframe = NS_STATIC_CAST(nsOutlinerBodyFrame*, frame);
oframe->InvalidateColumnCache();
}
}
}
}

View File

@ -40,6 +40,12 @@ public:
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull);
NS_IMETHODIMP Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, // Overridden to capture events
nsFramePaintLayer aWhichLayer,
@ -59,5 +65,9 @@ protected:
protected:
// Members.
void EnsureOutliner();
void InvalidateColumnCache(nsIPresContext* aPresContext);
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
}; // class nsOutlinerColFrame

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Ben Goodger <ben@netscape.com>
* Joe Hewitt <hewitt@netscape.com>
*/
#include "nsCOMPtr.h"
@ -253,6 +254,7 @@ nsOutlinerBodyFrame::nsOutlinerBodyFrame(nsIPresShell* aPresShell)
mAlreadyUndrewDueToScroll(PR_FALSE)
{
NS_NewISupportsArray(getter_AddRefs(mScratchArray));
mColumnsDirty = PR_TRUE;
}
// Destructor
@ -1037,8 +1039,6 @@ nsOutlinerBodyFrame::GetCoordsForCellItem(PRInt32 aRow, const PRUnichar *aColID,
return NS_OK;
}
nsresult
nsOutlinerBodyFrame::GetItemWithinCellAt(PRInt32 aX, const nsRect& aCellRect,
PRInt32 aRowIndex,
@ -1569,6 +1569,16 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintColumn(nsOutlinerColumn* aColumn,
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(aColumn->GetElement()));
mView->GetColumnProperties(aColumn->GetID(), elt, mScratchArray);
// Read special properties from attributes on the column content node
nsAutoString attr;
aColumn->GetElement()->GetAttr(kNameSpaceID_None, nsXULAtoms::insertbefore, attr);
if (attr.EqualsWithConversion("true"))
mScratchArray->AppendElement(nsXULAtoms::insertbefore);
attr.AssignWithConversion("");
aColumn->GetElement()->GetAttr(kNameSpaceID_None, nsXULAtoms::insertafter, attr);
if (attr.EqualsWithConversion("true"))
mScratchArray->AppendElement(nsXULAtoms::insertafter);
// Resolve style for the column. It contains all the info we need to lay ourselves
// out and to paint.
nsCOMPtr<nsIStyleContext> colContext;
@ -2327,10 +2337,19 @@ nsOutlinerBodyFrame::PseudoMatches(nsIAtom* aTag, nsCSSSelector* aSelector, PRBo
return NS_OK;
}
void
nsOutlinerBodyFrame::InvalidateColumnCache()
{
mColumnsDirty = PR_TRUE;
}
void
nsOutlinerBodyFrame::EnsureColumns()
{
if (!mColumns) {
if (!mColumns || mColumnsDirty) {
delete mColumns;
mColumnsDirty = PR_FALSE;
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
@ -2354,7 +2373,7 @@ nsOutlinerBodyFrame::EnsureColumns()
nsCOMPtr<nsIDOMNode> node;
cols->Item(0, getter_AddRefs(node));
nsCOMPtr<nsIContent> child(do_QueryInterface(node));
// Get the frame for this column.
nsIFrame* frame;
shell->GetPrimaryFrameFor(child, &frame);
@ -2365,26 +2384,28 @@ nsOutlinerBodyFrame::EnsureColumns()
frame->GetParent(&colContainer);
nsCOMPtr<nsIBox> colContainerBox(do_QueryInterface(colContainer));
PRBool isNormal = PR_TRUE;
colContainerBox->GetDirection(isNormal);
PRInt32 i = isNormal ? 0 : count-1;
nsIBox* colBox;
colContainerBox->GetChildBox(&colBox);
nsOutlinerColumn* currCol = nsnull;
for ( ; (isNormal ? (i < ((PRInt32)count)) : (i >= 0)); (isNormal ? i++ : i--)) {
nsCOMPtr<nsIDOMNode> node;
cols->Item(i, getter_AddRefs(node));
nsCOMPtr<nsIContent> child(do_QueryInterface(node));
// Get the frame for this column.
while (colBox) {
nsIFrame* frame;
shell->GetPrimaryFrameFor(child, &frame);
colBox->GetFrame(&frame);
nsCOMPtr<nsIContent> content;
frame->GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDOMElement> colElt(do_QueryInterface(content));
nsCOMPtr<nsIDOMNode> colParentElt;
colElt->GetParentNode(getter_AddRefs(colParentElt));
if (colParentElt == elt) {
// Create a new column structure.
nsOutlinerColumn* col = new nsOutlinerColumn(content, frame);
if (currCol)
currCol->SetNext(col);
else mColumns = col;
currCol = col;
}
// Create a new column structure.
nsOutlinerColumn* col = new nsOutlinerColumn(child, frame);
if (currCol)
currCol->SetNext(col);
else mColumns = col;
currCol = col;
colBox->GetNextBox(&colBox);
}
}
}

View File

@ -299,6 +299,10 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aRect, const nsRect& aDirtyRect);
// This method is called whenever an outlinercol is added or removed and
// the column cache needs to be rebuilt.
void InvalidateColumnCache();
friend nsresult NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame);
@ -402,6 +406,9 @@ protected: // Data Members
PRInt32 mRowHeight;
PRInt32 mIndentation;
// An indicator that columns have changed and need to be rebuilt
PRBool mColumnsDirty;
// A scratch array used when looking up cached style contexts.
nsCOMPtr<nsISupportsArray> mScratchArray;

View File

@ -33,6 +33,7 @@
#include "nsIDocument.h"
#include "nsIBoxObject.h"
#include "nsIDOMElement.h"
#include "nsOutlinerBodyFrame.h"
//
// NS_NewOutlinerColFrame
@ -84,6 +85,18 @@ nsOutlinerColFrame::~nsOutlinerColFrame()
{
}
NS_IMETHODIMP
nsOutlinerColFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
InvalidateColumnCache(aPresContext);
return rv;
}
NS_IMETHODIMP
nsOutlinerColFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
@ -162,24 +175,52 @@ nsOutlinerColFrame::AttributeChanged(nsIPresContext* aPresContext,
if (aAttribute == nsHTMLAtoms::width || aAttribute == nsHTMLAtoms::hidden) {
// Invalidate the outliner.
if (!mOutliner) {
// Get our parent node.
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
nsCOMPtr<nsIBoxObject> boxObject;
nsDoc->GetBoxObjectFor(elt, getter_AddRefs(boxObject));
mOutliner = do_QueryInterface(boxObject);
}
EnsureOutliner();
if (mOutliner)
mOutliner->Invalidate();
} else if (aAttribute == nsXULAtoms::ordinal) {
InvalidateColumnCache(aPresContext);
}
return rv;
}
void
nsOutlinerColFrame::EnsureOutliner()
{
if (!mOutliner && mContent) {
// Get our parent node.
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
nsCOMPtr<nsIBoxObject> boxObject;
nsDoc->GetBoxObjectFor(elt, getter_AddRefs(boxObject));
mOutliner = do_QueryInterface(boxObject);
}
}
void
nsOutlinerColFrame::InvalidateColumnCache(nsIPresContext* aPresContext)
{
EnsureOutliner();
if (mOutliner) {
nsCOMPtr<nsIDOMElement> bodyEl;
mOutliner->GetOutlinerBody(getter_AddRefs(bodyEl));
nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(bodyEl);
if (bodyContent) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsIFrame* frame;
shell->GetPrimaryFrameFor(bodyContent, &frame);
if (frame) {
nsOutlinerBodyFrame* oframe = NS_STATIC_CAST(nsOutlinerBodyFrame*, frame);
oframe->InvalidateColumnCache();
}
}
}
}

View File

@ -40,6 +40,12 @@ public:
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull);
NS_IMETHODIMP Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, // Overridden to capture events
nsFramePaintLayer aWhichLayer,
@ -59,5 +65,9 @@ protected:
protected:
// Members.
void EnsureOutliner();
void InvalidateColumnCache(nsIPresContext* aPresContext);
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
}; // class nsOutlinerColFrame

View File

@ -29,28 +29,28 @@ Rights Reserved.
<script src="chrome://messenger/content/threadPane.js"/>
<outliner id="threadOutliner" flex="1"
<outliner id="threadOutliner" flex="1" enableColumnDrag="true"
onkeypress="ThreadPaneKeyPress(event);">
<outlinercol id="threadCol" display="&threadColumn.label;" class="outlinercol-header outlinercol-image outlinercol-inset-header threadColumnHeader" currentView="unthreaded" cycler="true" persist="hidden" fixed="true" />
<outlinercol id="subjectCol" class="outlinercol-header outlinercell-inset-header sortDirectionIndicator" persist="hidden width" flex="7" label="&subjectColumn.label;" primary="true"/>
<outlinercol id="threadCol" display="&threadColumn.label;" class="outlinercol-header outlinercol-image outlinercol-inset-header threadColumnHeader" currentView="unthreaded" cycler="true" persist="hidden ordinal" fixed="true" />
<outlinercol id="subjectCol" class="outlinercol-header outlinercell-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="7" label="&subjectColumn.label;" primary="true"/>
<splitter class="tree-splitter"/>
<outlinercol id="senderOrRecipientCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="4" label="&senderColumn.label;"/>
<outlinercol id="senderOrRecipientCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="4" label="&senderColumn.label;"/>
<splitter class="tree-splitter"/>
<outlinercol id="unreadButtonColHeader" fixed="true" persist="hidden" class="outlinercol-header outlinercol-image outlinercol-inset-header readColumnHeader" display="&readColumn.label;" cycler="true"/>
<outlinercol id="unreadButtonColHeader" fixed="true" persist="hidden ordinal" class="outlinercol-header outlinercol-image outlinercol-inset-header readColumnHeader" display="&readColumn.label;" cycler="true"/>
<splitter class="tree-splitter"/>
<outlinercol id="dateCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="2" label="&dateColumn.label;"/>
<outlinercol id="dateCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="2" label="&dateColumn.label;"/>
<splitter class="tree-splitter"/>
<outlinercol id="statusCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="1" label="&statusColumn.label;"/>
<outlinercol id="statusCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="1" label="&statusColumn.label;"/>
<splitter class="tree-splitter"/>
<outlinercol id="sizeCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="1" label="&sizeColumn.label;"/>
<outlinercol id="sizeCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="1" label="&sizeColumn.label;"/>
<splitter class="tree-splitter"/>
<outlinercol id="flaggedCol" fixed="true" persist="hidden" class="outlinercol-header outlinercol-image outlinercol-inset-header flagColumnHeader" display="&flagColumn.label;" cycler="true"/>
<outlinercol id="flaggedCol" fixed="true" persist="hidden ordinal" class="outlinercol-header outlinercol-image outlinercol-inset-header flagColumnHeader" display="&flagColumn.label;" cycler="true"/>
<splitter class="tree-splitter"/>
<outlinercol id="priorityCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="1" label="&priorityColumn.label;"/>
<outlinercol id="priorityCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="1" label="&priorityColumn.label;"/>
<splitter class="tree-splitter"/>
<outlinercol id="unreadCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="1" label="&unreadColumn.label;"/>
<outlinercol id="unreadCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="1" label="&unreadColumn.label;"/>
<splitter class="tree-splitter"/>
<outlinercol id="totalCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden width" flex="1" label="&totalColumn.label;"/>
<outlinercol id="totalCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="hidden ordinal width" flex="1" label="&totalColumn.label;"/>
<outlinercol id="locationCol" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="width" flex="1" hidden="true" ignoreincolumnpicker="true" label="&locationColumn.label;"/>
<outlinerbody flex="1"
onselect="this.parentNode.outlinerBoxObject.view.selectionChanged();"

View File

@ -117,6 +117,42 @@ outlinercol:hover:active > .outlinercol-image-box
padding: 1px 1px 0px 2px;
}
/* column drag and drop styles */
outlinercol[dragging="true"] {
border: 1px solid ThreeDDarkShadow;
background-color: ThreeDShadow;
color: ThreeDHighlight;
}
outlinercol[dragging="true"] > .outlinercol-box {
border: 1px solid transparent;
}
outlinercol[insertafter="true"] {
border-right: 1px solid ThreeDDarkShadow;
}
outlinercol[insertafter="true"] > .outlinercol-box {
border-right: 1px solid ThreeDShadow;
}
outlinercol[insertbefore="true"] {
border-left: 1px solid ThreeDDarkShadow;
}
outlinercol[insertbefore="true"] > .outlinercol-box {
border-left: 1px solid ThreeDShadow;
}
outlinerbody:-moz-outliner-column(insertbefore) {
border-left: 1px solid ThreeDShadow;
}
outlinerbody:-moz-outliner-column(insertafter) {
border-right: 1px solid ThreeDShadow;
}
/* outliner header with sort direction indicators */
.outlinercol-sortdirection {

View File

@ -113,6 +113,42 @@ outlinercol:hover:active > .outlinercol-image-box {
padding: 1px 1px 0px 2px;
}
/* column drag and drop styles */
outlinercol[dragging="true"] {
border: 1px solid ThreeDDarkShadow;
background-color: ThreeDShadow;
color: ThreeDHighlight;
}
outlinercol[dragging="true"] > .outlinercol-box {
border: 1px solid transparent;
}
outlinercol[insertafter="true"] {
border-right: 1px solid ThreeDDarkShadow;
}
outlinercol[insertafter="true"] > .outlinercol-box {
border-right: 1px solid ThreeDShadow;
}
outlinercol[insertbefore="true"] {
border-left: 1px solid ThreeDDarkShadow;
}
outlinercol[insertbefore="true"] > .outlinercol-box {
border-left: 1px solid ThreeDShadow;
}
outlinerbody:-moz-outliner-column(insertbefore) {
border-left: 1px solid ThreeDShadow;
}
outlinerbody:-moz-outliner-column(insertafter) {
border-right: 1px solid ThreeDShadow;
}
/* outliner header with sort direction indicators */
.outlinercol-sortdirection {

View File

@ -76,6 +76,16 @@ outlinerbody:-moz-outliner-cell-text(selected, focus) {
color: #FFFFFF;
}
/* ::::: lines connecting cells ::::: */
outlinerbody:-moz-outliner-line {
border: 1px dotted #808080;
}
outlinerbody:-moz-outliner-line(selected, focus) {
border: 1px dotted #FFFFFF;
}
/* ::::: outliner columns ::::: */
outlinercol {
@ -87,12 +97,40 @@ outlinercol {
color: #000000;
}
outlinerbody:-moz-outliner-line {
border: 1px dotted #808080;
/* ::::: column drag and drop styles ::::: */
outlinercol[dragging="true"] {
border: 1px solid #000000;
background-color: #90A1B3;
color: #FFFFFF;
}
outlinerbody:-moz-outliner-line(selected, focus) {
border: 1px dotted #FFFFFF;
outlinercol[dragging="true"] > .outlinercol-box {
border: 1px solid transparent;
}
outlinercol[insertafter="true"] {
border-right: 1px solid #000000;
}
outlinercol[insertafter="true"] > .outlinercol-box {
border-right: 1px solid #666666;
}
outlinercol[insertbefore="true"] {
border-left: 1px solid #000000;
}
outlinercol[insertbefore="true"] > .outlinercol-box {
border-left: 1px solid #666666;
}
outlinerbody:-moz-outliner-column(insertbefore) {
border-left: 1px solid #AAAAAA;
}
outlinerbody:-moz-outliner-column(insertafter) {
border-right: 1px solid #AAAAAA;
}
/* ..... internal box ..... */

View File

@ -62,7 +62,7 @@
<data id="multipleBookmarks" label="&addToBookmarksCmd.label;" accesskey="&addToBookmarksCmd.accesskey;"/>
<data id="oneBookmark" label="&bookmarkLinkCmd.label;" accesskey="&bookmarkLinkCmd.accesskey;"/>
</popupset>
<outliner id="historyOutliner" flex="1"
<outliner id="historyOutliner" flex="1" enableColumnDrag="true"
onkeypress="if (event.keyCode == 13) OpenURL(event.ctrlKey || event.metaKey);">
<outlinerbody id="historyOutlinerBody" flex="1" datasources="rdf:history"
@ -94,7 +94,7 @@
</template>
</outlinerbody>
<outlinercol flex="4" id="Name" persist="hidden width sortActive sortDirection"
<outlinercol flex="4" id="Name" persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.name.label;" primary="true"
sort="rdf:http://home.netscape.com/NC-rdf#Name"
class="sortDirectionIndicator"/>
@ -102,42 +102,42 @@
<splitter class="tree-splitter" id="pre-URL-splitter"/>
<outlinercol flex="4" id="URL"
persist="hidden width sortActive sortDirection"
persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.url.label;" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#URL"/>
<splitter class="tree-splitter" id="pre-Date-splitter"/>
<outlinercol flex="1" id="Date" sortActive="true" sortDirection="descending"
persist="hidden width sortActive sortDirection"
persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.date.label;" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#Date"/>
<splitter class="tree-splitter" id="pre-FirstVisitDate-splitter"/>
<outlinercol flex="1" id="FirstVisitDate"
hidden="true" persist="hidden width sortActive sortDirection"
hidden="true" persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.firstvisitdate.label;" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#FirstVisitDate"/>
<splitter class="tree-splitter" id="pre-Hostname-splitter"/>
<outlinercol flex="1" id="Hostname" hidden="true"
persist="hidden width sortActive sortDirection"
persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.hostname.label;" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#Hostname"/>
<splitter class="tree-splitter" id="pre-Referrer-splitter"/>
<outlinercol flex="1" id="Referrer" hidden="true"
persist="hidden width sortActive sortDirection"
persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.referrer.label;" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#Referrer"/>
<splitter class="tree-splitter" id="pre-VisitCount-splitter"/>
<outlinercol flex="1" id="VisitCount"
hidden="true" persist="hidden width sortActive sortDirection"
hidden="true" persist="hidden width sortActive sortDirection ordinal"
label="&tree.header.visitcount.label;" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#VisitCount"/>

View File

@ -15,7 +15,7 @@
<content orient="vertical">
<xul:hbox class="outliner-columns">
<children includes="outlinercol|splitter"/>
<xul:outlinercol class="outliner-columnpicker" fixed="true"/>
<xul:outlinercol class="outliner-columnpicker" fixed="true" ordinal="2147483647"/>
</xul:hbox>
<xul:outlinerrows class="outliner-rows" flex="1">
<children/>
@ -38,6 +38,114 @@
<property name="singleSelection"
onget="return this.getAttribute('seltype') == 'single'"
readonly="true"/>
<property name="enableColumnDrag"
onget="return this.getAttribute('enableColumnDrag') == 'true';"
onset="this.setAttribute('enableColumnDrag', val); return val == 'true';"/>
<property name="firstOrdinalColumn">
<getter><![CDATA[
var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var cols = this.getElementsByTagNameNS(xulns, "outlinercol");
var parent = cols[0].boxObject.parentBox;
return parent.boxObject.firstChild;
]]></getter>
</property>
<property name="_columnsDirty">true</property>
<method name="_ensureColumnOrder">
<body><![CDATA[
if (this._columnsDirty) {
// update the ordinal position of each column to assure that it is
// an odd number and 2 positions above it's next sibling
var col = this.firstOrdinalColumn;
var cols = [];
while (col) {
if (col.localName == "outlinercol" && col.parentNode == this)
cols[cols.length] = col;
col = col.boxObject.nextSibling;
}
for (var i = 0; i < cols.length; ++i)
cols[i].setAttribute("ordinal", (i*2)+1);
// update the ordinal positions of splitters to even numbers, so that
// they are in between columns
var splitters = this.getElementsByTagName("splitter");
for (var i = 0; i < splitters.length; ++i)
splitters[i].setAttribute("ordinal", (i+1)*2);
this._columnsDirty = false;
}
]]></body>
</method>
<method name="_reorderColumn">
<parameter name="aColMove"/>
<parameter name="aColBefore"/>
<parameter name="aBefore"/>
<body><![CDATA[
var cols = [];
if (aColBefore.ordinal < aColMove.ordinal) {
var col = aColBefore;
while (col) {
if (col.localName == "outlinercol")
cols.push(col);
col = col.boxObject.nextSibling;
if (col == aColMove)
break;
}
aColMove.ordinal = aColBefore.ordinal;
for (var i = 0; i < cols.length; ++i)
cols[i].ordinal += 2;
} else {
var col = aColMove.boxObject.nextSibling;
while (col) {
if (col.localName == "outlinercol")
cols.push(col);
col = col.boxObject.nextSibling;
if (col == aColBefore && aBefore)
break;
}
aColMove.ordinal = aBefore ? aColBefore.ordinal-2 : aColBefore.ordinal;
for (var i = 0; i < cols.length; ++i)
cols[i].ordinal -= 2;
}
]]></body>
</method>
<method name="_getColumnAtX">
<parameter name="aX"/>
<parameter name="aThresh"/>
<parameter name="aPos"/>
<body><![CDATA[
if (aPos) aPos.value = "before";
var col = this.firstOrdinalColumn;
var lastCol = null;
var currentX = this.boxObject.x;
while (col) {
if (col.localName == "outlinercol" && col.parentNode == this) {
var cw = col.boxObject.width;
if (cw > 0) {
currentX += cw;
if (currentX - (cw*aThresh) > aX)
return col;
}
lastCol = col;
}
col = col.boxObject.nextSibling;
}
if (aPos) aPos.value = "after";
return lastCol;
]]></body>
</method>
</implementation>
<handlers>
@ -540,7 +648,145 @@
</handlers>
</binding>
<binding id="outlinercol" extends="chrome://global/content/bindings/outliner.xml#outliner-base">
<binding id="outlinercol-base" extends="chrome://global/content/bindings/outliner.xml#outliner-base">
<implementation>
<property name="ordinal">
<getter><![CDATA[
var val = this.getAttribute("ordinal");
return val == "" ? 1 : (val == "0" ? 0 : parseInt(val));
]]></getter>
<setter><![CDATA[
this.setAttribute("ordinal", val);
]]></setter>
</property>
<property name="_previousVisibleColumn">
<getter><![CDATA[
var sib = this.boxObject.previousSibling;
while (sib) {
if (sib.localName == "outlinercol" && sib.boxObject.width > 0 && sib.parentNode == this.parentNode)
return sib;
sib = sib.boxObject.previousSibling;
}
return null;
]]></getter>
</property>
<method name="onDragMouseMove">
<parameter name="aEvent"/>
<body><![CDATA[
var col = document.outlinercolDragging;
if (!col) return;
if (col.mDragGesturing) {
if (Math.abs(aEvent.clientX - col.mStartDragX) < 5 &&
Math.abs(aEvent.clientY - col.mStartDragY) < 5) {
return;
} else {
col.mDragGesturing = false;
col.setAttribute("dragging", "true");
}
}
var pos = {};
var targetCol = col.parentNode._getColumnAtX(aEvent.clientX, 0.5, pos);
if (col.mTargetCol == targetCol && col.mTargetDir == pos.value)
return;
if (col.mTargetCol) {
// remove previous insertbefore/after attributes
col.mTargetCol.removeAttribute("insertbefore");
col.mTargetCol.removeAttribute("insertafter");
var sib = col.mTargetCol.boxObject.previousSibling;
var sib = col.mTargetCol._previousVisibleColumn;
if (sib)
sib.removeAttribute("insertafter");
col.mTargetCol = null;
col.mTargetDir = null;
}
if (targetCol) {
// set insertbefore/after attributes
if (pos.value == "after") {
targetCol.setAttribute("insertafter", "true");
} else {
targetCol.setAttribute("insertbefore", "true");
var sib = targetCol._previousVisibleColumn;
if (sib)
sib.setAttribute("insertafter", "true");
}
col.mTargetCol = targetCol;
col.mTargetDir = pos.value;
}
// XXX should really just invalidate columns
// XXX need to implement nsIOutlinerBoxObject::invalidateColumn(in long column)
var bx = col.parentNode.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject);
bx.invalidate();
]]></body>
</method>
<method name="onDragMouseUp">
<parameter name="aEvent"/>
<body><![CDATA[
var col = document.outlinercolDragging;
if (!col) return;
col.removeAttribute("dragging", "true");
if (col.mTargetCol) {
// remove insertbefore/after attributes
var before = col.mTargetCol.hasAttribute("insertbefore");
col.mTargetCol.removeAttribute(before ? "insertbefore" : "insertafter");
if (before) {
var sib = col.mTargetCol.boxObject.previousSibling;
var sib = col.mTargetCol._previousVisibleColumn;
if (sib)
sib.removeAttribute("insertafter");
}
// move the column
if (col != col.mTargetCol)
col.parentNode._reorderColumn(col, col.mTargetCol, before);
// repaint to remove lines
var bx = col.parentNode.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject);
bx.invalidate();
col.mTargetCol = null;
}
document.outlinercolDragging = null;
]]></body>
</method>
</implementation>
<handlers>
<handler event="mousedown" button="0"><![CDATA[
if (this.parentNode.enableColumnDrag) {
var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var cols = this.parentNode.getElementsByTagNameNS(xulns, "outlinercol");
// only start column drag operation if there are at least 2 visible columns
var visible = 0;
for (var i = 0; i < cols.length; ++i)
if (cols[i].boxObject.width > 0) ++visible;
if (visible > 1) {
window.addEventListener("mousemove", this.onDragMouseMove, false);
window.addEventListener("mouseup", this.onDragMouseUp, false);
document.outlinercolDragging = this;
this.mDragGesturing = true;
this.mStartDragX = event.clientX;
this.mStartDragY = event.clientY;
}
}
]]></handler>
</handlers>
</binding>
<binding id="outlinercol" extends="chrome://global/content/bindings/outliner.xml#outlinercol-base">
<content>
<xul:hbox class="outlinercol-box" flex="1" align="center">
<xul:image class="outliner-image" inherits="src"/>
@ -553,7 +799,7 @@
</handlers>
</binding>
<binding id="outlinercol-image" extends="chrome://global/content/bindings/outliner.xml#outliner-base">
<binding id="outlinercol-image" extends="chrome://global/content/bindings/outliner.xml#outlinercol-base">
<content>
<xul:hbox class="outlinercol-image-box" flex="1" align="center">
<xul:image class="outlinercol-icon" inherits="src"/>