From 362e1987f88b01b86c2d94f0deea597f8e95bc2a Mon Sep 17 00:00:00 2001 From: "hyatt%netscape.com" Date: Wed, 9 Dec 1998 19:57:15 +0000 Subject: [PATCH] Modifications to make the tree widget talk to nsIContent. --- widget/src/xpwidgets/makefile.win | 4 +- widget/src/xpwidgets/nsHTColumn.cpp | 2 +- widget/src/xpwidgets/nsHTDataModel.cpp | 72 ++++++++++++++++--- widget/src/xpwidgets/nsHTDataModel.h | 19 ++++- widget/src/xpwidgets/nsHTItem.cpp | 47 +++++++++++- widget/src/xpwidgets/nsHTItem.h | 8 ++- widget/src/xpwidgets/nsHTTreeDataModel.cpp | 8 +++ widget/src/xpwidgets/nsHTTreeDataModel.h | 6 ++ widget/src/xpwidgets/nsHTTreeItem.cpp | 20 +++++- widget/src/xpwidgets/nsHTTreeItem.h | 4 +- widget/src/xpwidgets/nsHierarchicalDataItem.h | 9 ++- .../src/xpwidgets/nsHierarchicalDataModel.h | 3 + widget/src/xpwidgets/nsTreeView.cpp | 10 +++ widget/src/xpwidgets/nsTreeView.h | 9 ++- 14 files changed, 197 insertions(+), 24 deletions(-) diff --git a/widget/src/xpwidgets/makefile.win b/widget/src/xpwidgets/makefile.win index 00f6f7d684d4..644b719651fa 100644 --- a/widget/src/xpwidgets/makefile.win +++ b/widget/src/xpwidgets/makefile.win @@ -19,7 +19,7 @@ DEPTH=..\..\.. #IGNORE_MANIFEST=1 LIBRARY_NAME = raptorbasewidget_s -REQUIRES=xpcom gfxwin raptor +REQUIRES=xpcom gfxwin raptor dom js DEFINES =-D_IMPL_NS_WIDGET CPPSRCS = \ @@ -59,6 +59,8 @@ LINCS= \ -I$(PUBLIC)\raptor \ -I$(PUBLIC)\xpcom \ -I..\windows \ + -I$(PUBLIC)\dom \ + -I$(PUBLIC)\js \ $(NULL) LCFLAGS = \ diff --git a/widget/src/xpwidgets/nsHTColumn.cpp b/widget/src/xpwidgets/nsHTColumn.cpp index 87e1873bee18..4782bad8ece0 100644 --- a/widget/src/xpwidgets/nsHTColumn.cpp +++ b/widget/src/xpwidgets/nsHTColumn.cpp @@ -46,7 +46,7 @@ double nsHTColumn::GetDesiredPercentage() const void nsHTColumn::GetColumnName(nsString& name) const { - name = "Header"; + name = "Name"; } PRBool nsHTColumn::IsSortColumn() const diff --git a/widget/src/xpwidgets/nsHTDataModel.cpp b/widget/src/xpwidgets/nsHTDataModel.cpp index 23893b307aa3..f86a37d978bd 100644 --- a/widget/src/xpwidgets/nsHTDataModel.cpp +++ b/widget/src/xpwidgets/nsHTDataModel.cpp @@ -25,6 +25,9 @@ #include "nsTreeColumn.h" #include "nsHTTreeItem.h" #include "nsIDeviceContext.h" +#include "nsIDocument.h" +#include "nsIContent.h" +#include "nsVoidArray.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -32,10 +35,8 @@ nsHTDataModel::nsHTDataModel() { mListener = nsnull; mImageGroup = nsnull; - - // Init. one of our hard-coded values - mSingleNode = new nsHTTreeItem(); // TODO: This is all ridiculously illegal. - ((nsHTTreeItem*)mSingleNode)->SetDataModel((nsHTTreeDataModel*)this); // This is very bad. Just doing to test. + mContentRoot = nsnull; + mDocument = nsnull; } //-------------------------------------------------------------------- @@ -47,8 +48,7 @@ nsHTDataModel::~nsHTDataModel() NS_RELEASE(mImageGroup); } - // Delete hard-coded value - delete mSingleNode; + // TODO: Destroy visibility array } void nsHTDataModel::SetDataModelListenerDelegate(nsDataModelWidget* pWidget) @@ -65,10 +65,62 @@ void nsHTDataModel::SetDataModelListenerDelegate(nsDataModelWidget* pWidget) // Hierarchical Data Model Implementation --------------------- +void nsHTDataModel::SetContentRootDelegate(nsIContent* pContent) +{ + NS_IF_RELEASE(mDocument); + NS_IF_RELEASE(mContentRoot); + + mContentRoot = pContent; + pContent->GetDocument(mDocument); // I'm assuming this addrefs the document. + NS_ADDREF(mContentRoot); + + // Destroy our old visibility list. + // TODO + + // Reconstruct our visibility list (so that all items that are visible + // are instantiated). Need to only look for folder and item children. All other children should be ignored. + AddNodesToArray(mContentRoot); +} + +void nsHTDataModel::AddNodesToArray(nsIContent* pContent) +{ + // Add this child to the array (unless it is the root node). + nsHierarchicalDataItem* pDataItem = CreateDataItemWithContentNode(pContent); + if (pContent != mContentRoot) + mVisibleItemArray.AppendElement(pDataItem); + else mRootNode = pDataItem; + + nsHTItem* pItem = (nsHTItem*)(pDataItem->GetImplData()); + + nsIContent* pChildrenNode = pItem->FindChildWithName("children"); + if (pChildrenNode) + { + // If the node is OPEN, then its children need to be added to the visibility array. + nsString attrValue; + nsresult result = pContent->GetAttribute("open", attrValue); + if ((pContent == mContentRoot) || (result == NS_CONTENT_ATTR_NO_VALUE || + (result == NS_CONTENT_ATTR_HAS_VALUE && attrValue=="true"))) + { + PRInt32 numChildren = 0; + pChildrenNode->ChildCount(numChildren); + for (PRInt32 i = 0; i < numChildren; i++) + { + nsIContent* child = nsnull; + pContent->ChildAt(i, child); + if (child) + { + AddNodesToArray(child); + } + + NS_IF_RELEASE(child); + } + } + } +} nsHierarchicalDataItem* nsHTDataModel::GetRootDelegate() const { - return (nsHTTreeItem*)mSingleNode; + return mRootNode; } @@ -83,7 +135,11 @@ void nsHTDataModel::SetFirstVisibleItemIndexDelegate(PRUint32 n) nsHierarchicalDataItem* nsHTDataModel::GetNthItemDelegate(PRUint32 n) const { - return (nsHTTreeItem*)mSingleNode; + PRUint32 itemCount = (PRUint32)(mVisibleItemArray.Count()); + + if (n < itemCount) + return (nsHierarchicalDataItem*)(mVisibleItemArray[n]); + else return nsnull; } void nsHTDataModel::ImageLoaded(nsHierarchicalDataItem* pItem) diff --git a/widget/src/xpwidgets/nsHTDataModel.h b/widget/src/xpwidgets/nsHTDataModel.h index 7c02df0569a5..546ac748ac17 100644 --- a/widget/src/xpwidgets/nsHTDataModel.h +++ b/widget/src/xpwidgets/nsHTDataModel.h @@ -25,6 +25,8 @@ class nsDataModelWidget; class nsHTItem; +class nsIDocument; +class nsIContent; //------------------------------------------------------------ // The HyperTree Base Class @@ -40,6 +42,9 @@ public: nsHTDataModel(); virtual ~nsHTDataModel(); + // Set the content root + void SetContentRootDelegate(nsIContent* pContent); + // Retrieve the root node of the data model. virtual nsHierarchicalDataItem* GetRootDelegate() const; @@ -52,18 +57,28 @@ public: virtual void SetDataModelListenerDelegate(nsDataModelWidget* pListener); public: + virtual nsHierarchicalDataItem* CreateDataItemWithContentNode(nsIContent* pContent) = 0; + void ImageLoaded(nsHierarchicalDataItem* pItem); nsIImageGroup* GetImageGroup() const { NS_ADDREF(mImageGroup); return mImageGroup; } protected: + void AddNodesToArray(nsIContent* pContent); + // This recursive function is called to add nodes to the visibility array. + enum { cDMImageLoaded = 0 } ; nsDataModelWidget* mListener; // Events are sent to the listening widget. nsIImageGroup* mImageGroup; // Image group used for loading all images in the model. protected: - // Hard-coded values for testing. Will go away. - nsHTItem* mSingleNode; + // The document being observed (and the content node that serves as the root for the + // widget attached to the model). + nsIDocument* mDocument; + nsIContent* mContentRoot; + + nsHierarchicalDataItem* mRootNode; + nsVoidArray mVisibleItemArray; }; #endif /* nsToolbar_h___ */ diff --git a/widget/src/xpwidgets/nsHTItem.cpp b/widget/src/xpwidgets/nsHTItem.cpp index 554bc3ee5566..275a228cf040 100644 --- a/widget/src/xpwidgets/nsHTItem.cpp +++ b/widget/src/xpwidgets/nsHTItem.cpp @@ -19,14 +19,20 @@ #include "nspr.h" #include "nsString.h" #include "nsHTItem.h" +#include "nsIContent.h" +#include "nsIDOMNode.h" -nsHTItem::nsHTItem() +nsHTItem::nsHTItem(nsIContent* pContent, nsHierarchicalDataModel* pDataModel) { + NS_ADDREF(pContent); + mContentNode = pContent; + mDataModel = pDataModel; } //-------------------------------------------------------------------- nsHTItem::~nsHTItem() { + NS_IF_RELEASE(mContentNode); } PRBool nsHTItem::IsExpandedDelegate() const @@ -38,3 +44,42 @@ PRUint32 nsHTItem::GetIndentationLevelDelegate() const { return 0; } + +nsIContent* nsHTItem::FindChildWithName(const nsString& name) const +{ + PRInt32 count; + mContentNode->ChildCount(count); + for (PRInt32 i = 0; i < count; i++) + { + nsIAtom* pAtom = nsnull; + nsIContent* pChild = nsnull; + mContentNode->ChildAt(i, pChild); + pChild->GetTag(pAtom); + nsString answer; + pAtom->ToString(answer); + NS_IF_RELEASE(pAtom); + if (answer.EqualsIgnoreCase(name)) + return pChild; + else NS_IF_RELEASE(pChild); + } + + return nsnull; +} + +void nsHTItem::GetChildTextForNode(nsIContent* pChildNode, nsString& text) +{ + nsIContent* pChild; + pChildNode->ChildAt(0, pChild); + nsIDOMNode* pTextChild = nsnull; + +static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); + + if (pChild->QueryInterface(kIDOMNodeIID, (void**)&pTextChild)) + { + pTextChild->GetNodeValue(text); + NS_IF_RELEASE(pTextChild); + } + else text = "null"; + + NS_IF_RELEASE(pChild); +} diff --git a/widget/src/xpwidgets/nsHTItem.h b/widget/src/xpwidgets/nsHTItem.h index fb1e52cfb780..b6e2879f767e 100644 --- a/widget/src/xpwidgets/nsHTItem.h +++ b/widget/src/xpwidgets/nsHTItem.h @@ -20,21 +20,25 @@ #define nsHTItem_h___ class nsHierarchicalDataModel; +class nsIContent; class nsHTItem { public: - nsHTItem(); + nsHTItem(nsIContent* pContent, nsHierarchicalDataModel* pDataModel); virtual ~nsHTItem(); virtual PRBool IsExpandedDelegate() const; virtual PRUint32 GetIndentationLevelDelegate() const; - virtual void SetDataModelDelegate(nsHierarchicalDataModel* pDataModel) { mDataModel = pDataModel; } +public: + nsIContent* FindChildWithName(const nsString& name) const; // Caller must release the content ptr. + static void GetChildTextForNode(nsIContent* pChildNode, nsString& text); protected: nsHierarchicalDataModel* mDataModel; + nsIContent* mContentNode; }; #endif /* nsHTItem_h___ */ diff --git a/widget/src/xpwidgets/nsHTTreeDataModel.cpp b/widget/src/xpwidgets/nsHTTreeDataModel.cpp index 6d815f26d661..59d0d8018c2f 100644 --- a/widget/src/xpwidgets/nsHTTreeDataModel.cpp +++ b/widget/src/xpwidgets/nsHTTreeDataModel.cpp @@ -28,6 +28,7 @@ #include "nsIImageObserver.h" #include "nsIImageRequest.h" #include "nsIImageGroup.h" +#include "nsHTTreeItem.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID); @@ -292,3 +293,10 @@ void nsHTTreeDataModel::NotifyError(nsIImageRequest *aImageRequest, nsImageError aErrorType) { } + +// Inherited functions from nsHTDataModel +nsHierarchicalDataItem* nsHTTreeDataModel::CreateDataItemWithContentNode(nsIContent* pContent) +{ + nsHTTreeItem* pItem = new nsHTTreeItem(pContent, this); + return pItem; +} \ No newline at end of file diff --git a/widget/src/xpwidgets/nsHTTreeDataModel.h b/widget/src/xpwidgets/nsHTTreeDataModel.h index b1a5601477d8..6b2d127933c3 100644 --- a/widget/src/xpwidgets/nsHTTreeDataModel.h +++ b/widget/src/xpwidgets/nsHTTreeDataModel.h @@ -56,6 +56,8 @@ public: // Functions inherited from abstract hierarchical data model should be delegated to our // concrete base class + // Setting the Content Root for the tree + virtual void SetContentRoot(nsIContent* pContent) { SetContentRootDelegate(pContent); } virtual nsHierarchicalDataItem* GetRoot() const { return GetRootDelegate(); } virtual PRUint32 GetFirstVisibleItemIndex() const { return GetFirstVisibleItemIndexDelegate(); }; virtual void SetFirstVisibleItemIndex(PRUint32 index) { SetFirstVisibleItemIndexDelegate(index); }; @@ -91,6 +93,10 @@ public: // Text for the title bar, control strip and column headers virtual void GetTitleBarText(nsString& text) const; +public: + // Inherited functions from HTDataModel go here. + nsHierarchicalDataItem* CreateDataItemWithContentNode(nsIContent* pContent); + protected: nsIImageRequest* RequestImage(nsString& reqUrl) const; // Helper to kick off the image load. nsIImage* GetTitleBGImage() const; diff --git a/widget/src/xpwidgets/nsHTTreeItem.cpp b/widget/src/xpwidgets/nsHTTreeItem.cpp index fae54111b6fb..1fc8914ec8e1 100644 --- a/widget/src/xpwidgets/nsHTTreeItem.cpp +++ b/widget/src/xpwidgets/nsHTTreeItem.cpp @@ -18,6 +18,7 @@ #include "nspr.h" #include "nsString.h" +#include "nsHTColumn.h" #include "nsHTTreeItem.h" #include "nsHTTreeDataModel.h" #include "nsWidgetsCID.h" @@ -25,6 +26,7 @@ #include "nsIImageObserver.h" #include "nsIImageRequest.h" #include "nsIImageGroup.h" +#include "nsIContent.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID); @@ -32,7 +34,8 @@ static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID); NS_IMPL_ADDREF(nsHTTreeItem) NS_IMPL_RELEASE(nsHTTreeItem) -nsHTTreeItem::nsHTTreeItem() : nsTreeItem(), nsHTItem() +nsHTTreeItem::nsHTTreeItem(nsIContent* pContent, nsHierarchicalDataModel* pModel) +: nsTreeItem(), nsHTItem(pContent, pModel) { NS_INIT_REFCNT(); mClosedIconRequest = nsnull; @@ -40,11 +43,14 @@ nsHTTreeItem::nsHTTreeItem() : nsTreeItem(), nsHTItem() mClosedTriggerRequest = nsnull; mOpenTriggerRequest = nsnull; mBackgroundRequest = nsnull; + + SetImplData((void*)(nsHTItem*)this); } //-------------------------------------------------------------------- nsHTTreeItem::~nsHTTreeItem() { + NS_IF_RELEASE(mContentNode); } // ISupports Implementation -------------------------------------------------------------------- @@ -168,7 +174,17 @@ nsIImageRequest* nsHTTreeItem::RequestImage(nsString& reqUrl) const void nsHTTreeItem::GetTextForColumn(nsTreeColumn* pColumn, nsString& nodeText) const { - nodeText = "Node Stuff"; + nsString text("Node Stuff"); + nsString columnName; + pColumn->GetColumnName(columnName); + + // Look for a child of the content node that has this name as its tag. + nsIContent* pColumnNode = FindChildWithName("columns"); + if (pColumnNode) + { + nsIContent* pChildNode = FindChildWithName(columnName); + nsHTItem::GetChildTextForNode(pChildNode, nodeText); + } } // image request observer implementation diff --git a/widget/src/xpwidgets/nsHTTreeItem.h b/widget/src/xpwidgets/nsHTTreeItem.h index eb9c8540c708..2df68c1f6580 100644 --- a/widget/src/xpwidgets/nsHTTreeItem.h +++ b/widget/src/xpwidgets/nsHTTreeItem.h @@ -25,6 +25,7 @@ class nsHTDataModel; class nsIImageGroup; +class nsIContent; //------------------------------------------------------------ // This class functions as the data source for column information (things like @@ -34,7 +35,7 @@ class nsHTTreeItem : public nsTreeItem, public nsHTItem, public nsIImageRequestO { public: - nsHTTreeItem(); + nsHTTreeItem(nsIContent* pContent, nsHierarchicalDataModel* pModel); virtual ~nsHTTreeItem(); // Isupports interface ------------------ @@ -55,7 +56,6 @@ public: // the concrete implementation. virtual PRBool IsExpanded() const { return IsExpandedDelegate(); }; virtual PRUint32 GetIndentationLevel() const { return GetIndentationLevelDelegate(); }; - virtual void SetDataModel(nsHierarchicalDataModel* pDataModel) { SetDataModelDelegate(pDataModel); }; // End of delegated functions virtual void GetItemStyle(nsIDeviceContext* dc, diff --git a/widget/src/xpwidgets/nsHierarchicalDataItem.h b/widget/src/xpwidgets/nsHierarchicalDataItem.h index 46bdfe204f7d..c61c14fa147a 100644 --- a/widget/src/xpwidgets/nsHierarchicalDataItem.h +++ b/widget/src/xpwidgets/nsHierarchicalDataItem.h @@ -36,8 +36,13 @@ public: virtual PRBool IsExpanded() const = 0; virtual PRUint32 GetIndentationLevel() const = 0; - - virtual void SetDataModel(nsHierarchicalDataModel* pDataModel) = 0; + +public: + void* GetImplData() { return mImplData; } + void SetImplData(void* pData) { mImplData = pData; } + +protected: + void* mImplData; }; #endif /* nsHierarchicalDataItem_h___ */ diff --git a/widget/src/xpwidgets/nsHierarchicalDataModel.h b/widget/src/xpwidgets/nsHierarchicalDataModel.h index feff6cc3ee90..8262123bd657 100644 --- a/widget/src/xpwidgets/nsHierarchicalDataModel.h +++ b/widget/src/xpwidgets/nsHierarchicalDataModel.h @@ -21,6 +21,7 @@ class nsHierarchicalDataItem; class nsDataModelWidget; +class nsIContent; // Style info helper struct shared by most widgets. struct nsBasicStyleInfo @@ -54,6 +55,8 @@ public: virtual ~nsHierarchicalDataModel() {}; // Retrieve the root node of the data model. + // Setting the Content Root for the tree + virtual void SetContentRoot(nsIContent* pContent) = 0; virtual nsHierarchicalDataItem* GetRoot() const = 0; // A visibility hint can be stored and retrieved (e.g., the leftmost or topmost diff --git a/widget/src/xpwidgets/nsTreeView.cpp b/widget/src/xpwidgets/nsTreeView.cpp index 71a77a0e07b5..484ec3635826 100644 --- a/widget/src/xpwidgets/nsTreeView.cpp +++ b/widget/src/xpwidgets/nsTreeView.cpp @@ -98,6 +98,16 @@ nsresult nsTreeView::QueryInterface(REFNSIID aIID, void** aInstancePtr) return (nsWindow::QueryInterface(aIID, aInstancePtr)); } +NS_METHOD nsTreeView::SetContentRoot(nsIContent* pContent) +{ + if (mDataModel) + { + mDataModel->SetContentRoot(pContent); + } + + return NS_OK; +} + void nsTreeView::HandleDataModelEvent(int anEvent, nsHierarchicalDataItem* pItem) { Invalidate(PR_FALSE); diff --git a/widget/src/xpwidgets/nsTreeView.h b/widget/src/xpwidgets/nsTreeView.h index 76c65b8b3bb6..ddb3207f52a8 100644 --- a/widget/src/xpwidgets/nsTreeView.h +++ b/widget/src/xpwidgets/nsTreeView.h @@ -50,7 +50,9 @@ public: // nsISupports Interface -------------------------------- NS_DECL_ISUPPORTS - void HandleDataModelEvent(int event, nsHierarchicalDataItem* pItem); + // nsITreeView Interface -------------------------------- + NS_IMETHOD SetContentRoot(nsIContent* pContent); + NS_IMETHOD_(nsEventStatus) HandleEvent(nsGUIEvent *aEvent); // Override the widget creation method NS_IMETHOD Create(nsIWidget *aParent, @@ -61,6 +63,9 @@ public: nsIToolkit *aToolkit, nsWidgetInitData *aInitData); + + void HandleDataModelEvent(int event, nsHierarchicalDataItem* pItem); + protected: enum { cIndentAmount = 19, cIconMargin = 2, cMinColumnWidth = 30 }; @@ -107,8 +112,6 @@ protected: void DrawCroppedString(nsIRenderingContext* drawCtx, nsString text, const nsRect& rect); - NS_IMETHOD_(nsEventStatus) HandleEvent(nsGUIEvent *aEvent); - protected: // Data members nsTreeDataModel* mDataModel; // The data source from which everything to draw is obtained.