Fix for 71139. r=danm, sr=brendan

This commit is contained in:
hyatt%netscape.com 2001-03-08 00:46:58 +00:00
Родитель 44570a6c2d
Коммит 826e25f532
13 изменённых файлов: 269 добавлений и 66 удалений

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

@ -10,15 +10,16 @@
var view = ({
rowCount : 5000000,
getRowProperties : function(index, prop) {},
getCellProperties : function(index, prop) {},
outliner : null,
setOutliner : function(out) { this.outliner = out; },
getCellProperties : function(index, col, prop) {},
getColumnProperties : function(col, elt, prop) {},
outlinerbox : null,
setOutliner : function(out) { this.outlinerbox = out; },
getCellText : function(i, col) { return "Text at row #" + i + " in col " + col; }
});
function setView(outliner, v) {
dump('Outliner is ' + outliner + '\n');
outliner.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject).view = v;
outliner.outlinerBoxObject.view = v;
}
</script>

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

@ -36,6 +36,9 @@ interface nsIOutlinerBoxObject : nsISupports
// outliner tag or by setting this attribute to a new value.
attribute nsIOutlinerView view;
// Whether or not we are currently focused.
attribute boolean focused;
// Obtain the outlinerbody content node
readonly attribute nsIDOMElement outlinerBody;

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

@ -66,6 +66,9 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
long getRangeCount();
void getRangeAt(in long i, out long min, out long max);
// Can be used to invalidate the selection.
void invalidateSelection();
// Called when the row count changes to adjust selection indices.
void adjustSelection(in long index, in long count);

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

@ -33,6 +33,7 @@
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsCSSAtoms.h"
#include "nsIContent.h"
#include "nsIStyleContext.h"
@ -52,6 +53,7 @@
#include "nsIView.h"
#include "nsWidgetsCID.h"
#include "nsBoxFrame.h"
#include "nsBoxObject.h"
#define ELLIPSIS "..."
@ -199,7 +201,7 @@ NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
// Constructor
nsOutlinerBodyFrame::nsOutlinerBodyFrame(nsIPresShell* aPresShell)
:nsLeafBoxFrame(aPresShell), mPresContext(nsnull),
:nsLeafBoxFrame(aPresShell), mPresContext(nsnull), mOutlinerBoxObject(nsnull), mFocused(PR_FALSE),
mTopRowIndex(0), mRowHeight(0), mIndentation(0), mColumns(nsnull), mScrollbar(nsnull)
{
NS_NewISupportsArray(getter_AddRefs(mScratchArray));
@ -308,6 +310,12 @@ NS_IMETHODIMP nsOutlinerBodyFrame::GetView(nsIOutlinerView * *aView)
NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
{
// First clear out the old view.
if (mView) {
mView->SetOutliner(nsnull);
mView = nsnull;
}
// Outliner, meet the view.
mView = aView;
@ -320,7 +328,7 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
if (mView) {
// View, meet the outliner.
mView->SetOutliner(this);
mView->SetOutliner(mOutlinerBoxObject);
// Give the view a new empty selection object to play with.
nsCOMPtr<nsIOutlinerSelection> sel;
@ -335,6 +343,26 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBodyFrame::GetFocused(PRBool* aFocused)
{
*aFocused = mFocused;
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBodyFrame::SetFocused(PRBool aFocused)
{
mFocused = aFocused;
if (mView) {
nsCOMPtr<nsIOutlinerSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
if (sel)
sel->InvalidateSelection();
}
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBodyFrame::GetOutlinerBody(nsIDOMElement** aElement)
{
@ -429,9 +457,16 @@ nsOutlinerBodyFrame::UpdateScrollbar()
NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar()
{
if (!mScrollbar)
if (!mScrollbar) {
// Try to find it.
mScrollbar = InitScrollbarFrame(mPresContext, mParent, this);
nsCOMPtr<nsIContent> parContent;
mContent->GetParent(*getter_AddRefs(parContent));
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
nsIFrame* outlinerFrame;
shell->GetPrimaryFrameFor(parContent, &outlinerFrame);
mScrollbar = InitScrollbarFrame(mPresContext, outlinerFrame, this);
}
if (!mScrollbar || !mView)
return NS_OK;
@ -571,10 +606,14 @@ NS_IMETHODIMP nsOutlinerBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCoun
void
nsOutlinerBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, const PRUnichar* aColID)
{
// XXX Automatically fill in the following props: container, open, selected, focused
// And colID too, if it is non-empty.
// XXX Automatically fill in the following props: container, open
// And colID too, if it is non-empty?
mScratchArray->Clear();
// Check for focus.
if (mFocused)
mScratchArray->AppendElement(nsXULAtoms::focus);
if (aRowIndex != -1) {
nsCOMPtr<nsIOutlinerSelection> selection;
mView->GetSelection(getter_AddRefs(selection));
@ -685,12 +724,13 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
// Update our page count, our available height and our row height.
PRInt32 oldRowHeight = mRowHeight;
PRInt32 oldPageCount = mPageCount;
mRowHeight = GetRowHeight();
mIndentation = GetIndentation();
mInnerBox = GetInnerBox();
mPageCount = mInnerBox.height/mRowHeight;
if (mRowHeight != oldRowHeight)
if (mRowHeight != oldRowHeight || oldPageCount != mPageCount)
InvalidateScrollbar();
PRInt32 rowCount = 0;

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

@ -226,10 +226,15 @@ public:
friend nsresult NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame);
friend class nsOutlinerBoxObject;
protected:
nsOutlinerBodyFrame(nsIPresShell* aPresShell);
virtual ~nsOutlinerBodyFrame();
// Caches our box object.
void SetBoxObject(nsIOutlinerBoxObject* aBoxObject) { mOutlinerBoxObject = aBoxObject; };
// Returns the height of rows in the tree.
PRInt32 GetRowHeight();
@ -260,10 +265,16 @@ protected: // Data Members
// Our cached pres context.
nsIPresContext* mPresContext;
// The cached box object parent.
nsIOutlinerBoxObject* mOutlinerBoxObject;
// The current view for this outliner widget. We get all of our row and cell data
// from the view.
nsCOMPtr<nsIOutlinerView> mView;
// Whether or not we're currently focused.
PRBool mFocused;
// A cache of all the style contexts we have seen for rows and cells of the tree. This is a mapping from
// a list of atoms to a corresponding style context. This cache stores every combination that
// occurs in the tree, so for n distinct properties, this cache could have 2 to the n entries

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

@ -27,6 +27,9 @@
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIFrame.h"
#include "nsOutlinerBodyFrame.h"
#include "nsIAtom.h"
#include "nsXULAtoms.h"
class nsOutlinerBoxObject : public nsIOutlinerBoxObject, public nsBoxObject
{
@ -42,7 +45,8 @@ public:
//NS_PIBOXOBJECT interfaces
NS_IMETHOD Init(nsIContent* aContent, nsIPresShell* aPresShell);
NS_IMETHOD SetDocument(nsIDocument* aDocument);
nsIOutlinerBoxObject* mOutlinerBody;
};
/* Implementation file */
@ -60,6 +64,7 @@ nsOutlinerBoxObject::SetDocument(nsIDocument* aDocument)
nsOutlinerBoxObject::nsOutlinerBoxObject()
:mOutlinerBody(nsnull)
{
NS_INIT_ISUPPORTS();
}
@ -77,41 +82,55 @@ NS_IMETHODIMP nsOutlinerBoxObject::Init(nsIContent* aContent, nsIPresShell* aPre
return NS_OK;
}
nsIOutlinerBoxObject*
static void FindBodyElement(nsIContent* aParent, nsIContent** aResult)
{
nsCOMPtr<nsIAtom> tag;
aParent->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsXULAtoms::outlinerbody) {
*aResult = aParent;
NS_IF_ADDREF(*aResult);
}
else {
PRInt32 count;
aParent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIContent> child;
aParent->ChildAt(i, *getter_AddRefs(child));
FindBodyElement(child, aResult);
if (*aResult)
break;
}
}
}
inline nsIOutlinerBoxObject*
nsOutlinerBoxObject::GetOutlinerBody()
{
if (mOutlinerBody)
return mOutlinerBody;
nsIFrame* frame = GetFrame();
if (!frame)
return nsnull;
// For now we assume that the outliner body is under child 1 somewhere (since child 0 holds
// the columns).
nsCOMPtr<nsIPresContext> cx;
mPresShell->GetPresContext(getter_AddRefs(cx));
// Iterate over our content model children looking for the body.
nsCOMPtr<nsIContent> startContent;
frame->GetContent(getter_AddRefs(startContent));
nsIFrame* currFrame;
frame->FirstChild(cx, nsnull, &currFrame);
if (!currFrame)
return nsnull;
nsCOMPtr<nsIContent> content;
FindBodyElement(startContent, getter_AddRefs(content));
currFrame->GetNextSibling(&currFrame);
if (!currFrame)
return nsnull;
mPresShell->GetPrimaryFrameFor(content, &frame);
nsIFrame* childFrame;
currFrame->FirstChild(cx, nsnull, &childFrame);
while (childFrame) {
nsIOutlinerBoxObject* result = nsnull;
childFrame->QueryInterface(NS_GET_IID(nsIOutlinerBoxObject), (void**)&result);
if (result)
return result;
childFrame->GetNextSibling(&childFrame);
}
// It's a frame. Refcounts are irrelevant.
frame->QueryInterface(NS_GET_IID(nsIOutlinerBoxObject), (void**)&mOutlinerBody);
return nsnull;
nsOutlinerBodyFrame* bodyFrame = NS_STATIC_CAST(nsOutlinerBodyFrame*, frame);
bodyFrame->SetBoxObject(this);
return mOutlinerBody;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetView(nsIOutlinerView * *aView)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
@ -128,6 +147,22 @@ NS_IMETHODIMP nsOutlinerBoxObject::SetView(nsIOutlinerView * aView)
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetFocused(PRBool* aFocused)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->GetFocused(aFocused);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::SetFocused(PRBool aFocused)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->SetFocused(aFocused);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetOutlinerBody(nsIDOMElement** aElement)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();

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

@ -540,6 +540,15 @@ NS_IMETHODIMP nsOutlinerSelection::SetCurrentIndex(PRInt32 aIndex)
NS_IMETHODIMP
nsOutlinerSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
{
// XXX Write me!
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerSelection::InvalidateSelection()
{
if (mFirstRange)
mFirstRange->Invalidate();
return NS_OK;
}

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

@ -36,6 +36,9 @@ interface nsIOutlinerBoxObject : nsISupports
// outliner tag or by setting this attribute to a new value.
attribute nsIOutlinerView view;
// Whether or not we are currently focused.
attribute boolean focused;
// Obtain the outlinerbody content node
readonly attribute nsIDOMElement outlinerBody;

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

@ -66,6 +66,9 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
long getRangeCount();
void getRangeAt(in long i, out long min, out long max);
// Can be used to invalidate the selection.
void invalidateSelection();
// Called when the row count changes to adjust selection indices.
void adjustSelection(in long index, in long count);

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

@ -33,6 +33,7 @@
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsCSSAtoms.h"
#include "nsIContent.h"
#include "nsIStyleContext.h"
@ -52,6 +53,7 @@
#include "nsIView.h"
#include "nsWidgetsCID.h"
#include "nsBoxFrame.h"
#include "nsBoxObject.h"
#define ELLIPSIS "..."
@ -199,7 +201,7 @@ NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
// Constructor
nsOutlinerBodyFrame::nsOutlinerBodyFrame(nsIPresShell* aPresShell)
:nsLeafBoxFrame(aPresShell), mPresContext(nsnull),
:nsLeafBoxFrame(aPresShell), mPresContext(nsnull), mOutlinerBoxObject(nsnull), mFocused(PR_FALSE),
mTopRowIndex(0), mRowHeight(0), mIndentation(0), mColumns(nsnull), mScrollbar(nsnull)
{
NS_NewISupportsArray(getter_AddRefs(mScratchArray));
@ -308,6 +310,12 @@ NS_IMETHODIMP nsOutlinerBodyFrame::GetView(nsIOutlinerView * *aView)
NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
{
// First clear out the old view.
if (mView) {
mView->SetOutliner(nsnull);
mView = nsnull;
}
// Outliner, meet the view.
mView = aView;
@ -320,7 +328,7 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
if (mView) {
// View, meet the outliner.
mView->SetOutliner(this);
mView->SetOutliner(mOutlinerBoxObject);
// Give the view a new empty selection object to play with.
nsCOMPtr<nsIOutlinerSelection> sel;
@ -335,6 +343,26 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBodyFrame::GetFocused(PRBool* aFocused)
{
*aFocused = mFocused;
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBodyFrame::SetFocused(PRBool aFocused)
{
mFocused = aFocused;
if (mView) {
nsCOMPtr<nsIOutlinerSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
if (sel)
sel->InvalidateSelection();
}
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBodyFrame::GetOutlinerBody(nsIDOMElement** aElement)
{
@ -429,9 +457,16 @@ nsOutlinerBodyFrame::UpdateScrollbar()
NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar()
{
if (!mScrollbar)
if (!mScrollbar) {
// Try to find it.
mScrollbar = InitScrollbarFrame(mPresContext, mParent, this);
nsCOMPtr<nsIContent> parContent;
mContent->GetParent(*getter_AddRefs(parContent));
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
nsIFrame* outlinerFrame;
shell->GetPrimaryFrameFor(parContent, &outlinerFrame);
mScrollbar = InitScrollbarFrame(mPresContext, outlinerFrame, this);
}
if (!mScrollbar || !mView)
return NS_OK;
@ -571,10 +606,14 @@ NS_IMETHODIMP nsOutlinerBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCoun
void
nsOutlinerBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, const PRUnichar* aColID)
{
// XXX Automatically fill in the following props: container, open, selected, focused
// And colID too, if it is non-empty.
// XXX Automatically fill in the following props: container, open
// And colID too, if it is non-empty?
mScratchArray->Clear();
// Check for focus.
if (mFocused)
mScratchArray->AppendElement(nsXULAtoms::focus);
if (aRowIndex != -1) {
nsCOMPtr<nsIOutlinerSelection> selection;
mView->GetSelection(getter_AddRefs(selection));
@ -685,12 +724,13 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
// Update our page count, our available height and our row height.
PRInt32 oldRowHeight = mRowHeight;
PRInt32 oldPageCount = mPageCount;
mRowHeight = GetRowHeight();
mIndentation = GetIndentation();
mInnerBox = GetInnerBox();
mPageCount = mInnerBox.height/mRowHeight;
if (mRowHeight != oldRowHeight)
if (mRowHeight != oldRowHeight || oldPageCount != mPageCount)
InvalidateScrollbar();
PRInt32 rowCount = 0;

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

@ -226,10 +226,15 @@ public:
friend nsresult NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame);
friend class nsOutlinerBoxObject;
protected:
nsOutlinerBodyFrame(nsIPresShell* aPresShell);
virtual ~nsOutlinerBodyFrame();
// Caches our box object.
void SetBoxObject(nsIOutlinerBoxObject* aBoxObject) { mOutlinerBoxObject = aBoxObject; };
// Returns the height of rows in the tree.
PRInt32 GetRowHeight();
@ -260,10 +265,16 @@ protected: // Data Members
// Our cached pres context.
nsIPresContext* mPresContext;
// The cached box object parent.
nsIOutlinerBoxObject* mOutlinerBoxObject;
// The current view for this outliner widget. We get all of our row and cell data
// from the view.
nsCOMPtr<nsIOutlinerView> mView;
// Whether or not we're currently focused.
PRBool mFocused;
// A cache of all the style contexts we have seen for rows and cells of the tree. This is a mapping from
// a list of atoms to a corresponding style context. This cache stores every combination that
// occurs in the tree, so for n distinct properties, this cache could have 2 to the n entries

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

@ -27,6 +27,9 @@
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIFrame.h"
#include "nsOutlinerBodyFrame.h"
#include "nsIAtom.h"
#include "nsXULAtoms.h"
class nsOutlinerBoxObject : public nsIOutlinerBoxObject, public nsBoxObject
{
@ -42,7 +45,8 @@ public:
//NS_PIBOXOBJECT interfaces
NS_IMETHOD Init(nsIContent* aContent, nsIPresShell* aPresShell);
NS_IMETHOD SetDocument(nsIDocument* aDocument);
nsIOutlinerBoxObject* mOutlinerBody;
};
/* Implementation file */
@ -60,6 +64,7 @@ nsOutlinerBoxObject::SetDocument(nsIDocument* aDocument)
nsOutlinerBoxObject::nsOutlinerBoxObject()
:mOutlinerBody(nsnull)
{
NS_INIT_ISUPPORTS();
}
@ -77,41 +82,55 @@ NS_IMETHODIMP nsOutlinerBoxObject::Init(nsIContent* aContent, nsIPresShell* aPre
return NS_OK;
}
nsIOutlinerBoxObject*
static void FindBodyElement(nsIContent* aParent, nsIContent** aResult)
{
nsCOMPtr<nsIAtom> tag;
aParent->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsXULAtoms::outlinerbody) {
*aResult = aParent;
NS_IF_ADDREF(*aResult);
}
else {
PRInt32 count;
aParent->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
nsCOMPtr<nsIContent> child;
aParent->ChildAt(i, *getter_AddRefs(child));
FindBodyElement(child, aResult);
if (*aResult)
break;
}
}
}
inline nsIOutlinerBoxObject*
nsOutlinerBoxObject::GetOutlinerBody()
{
if (mOutlinerBody)
return mOutlinerBody;
nsIFrame* frame = GetFrame();
if (!frame)
return nsnull;
// For now we assume that the outliner body is under child 1 somewhere (since child 0 holds
// the columns).
nsCOMPtr<nsIPresContext> cx;
mPresShell->GetPresContext(getter_AddRefs(cx));
// Iterate over our content model children looking for the body.
nsCOMPtr<nsIContent> startContent;
frame->GetContent(getter_AddRefs(startContent));
nsIFrame* currFrame;
frame->FirstChild(cx, nsnull, &currFrame);
if (!currFrame)
return nsnull;
nsCOMPtr<nsIContent> content;
FindBodyElement(startContent, getter_AddRefs(content));
currFrame->GetNextSibling(&currFrame);
if (!currFrame)
return nsnull;
mPresShell->GetPrimaryFrameFor(content, &frame);
nsIFrame* childFrame;
currFrame->FirstChild(cx, nsnull, &childFrame);
while (childFrame) {
nsIOutlinerBoxObject* result = nsnull;
childFrame->QueryInterface(NS_GET_IID(nsIOutlinerBoxObject), (void**)&result);
if (result)
return result;
childFrame->GetNextSibling(&childFrame);
}
// It's a frame. Refcounts are irrelevant.
frame->QueryInterface(NS_GET_IID(nsIOutlinerBoxObject), (void**)&mOutlinerBody);
return nsnull;
nsOutlinerBodyFrame* bodyFrame = NS_STATIC_CAST(nsOutlinerBodyFrame*, frame);
bodyFrame->SetBoxObject(this);
return mOutlinerBody;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetView(nsIOutlinerView * *aView)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
@ -128,6 +147,22 @@ NS_IMETHODIMP nsOutlinerBoxObject::SetView(nsIOutlinerView * aView)
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetFocused(PRBool* aFocused)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->GetFocused(aFocused);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::SetFocused(PRBool aFocused)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->SetFocused(aFocused);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetOutlinerBody(nsIDOMElement** aElement)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();

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

@ -540,6 +540,15 @@ NS_IMETHODIMP nsOutlinerSelection::SetCurrentIndex(PRInt32 aIndex)
NS_IMETHODIMP
nsOutlinerSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
{
// XXX Write me!
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerSelection::InvalidateSelection()
{
if (mFirstRange)
mFirstRange->Invalidate();
return NS_OK;
}