Content model changes to get the tree widget alive.

This commit is contained in:
waterson%netscape.com 1998-12-09 03:25:33 +00:00
Родитель 0dc62760dc
Коммит 853da1faac
6 изменённых файлов: 219 добавлений и 95 удалений

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

@ -57,7 +57,7 @@ public:
* "content children," that is, a set of nsIRDFContent elements that * "content children," that is, a set of nsIRDFContent elements that
* should appear as the node's children in the content model. * should appear as the node's children in the content model.
*/ */
NS_IMETHOD CreateChildren(nsIRDFContent* element, nsISupportsArray* children) = 0; NS_IMETHOD CreateChildren(nsIRDFContent* element) = 0;
// XXX these should probably be strings so you can mess with them // XXX these should probably be strings so you can mess with them
// via the DOM. // via the DOM.

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

@ -1157,7 +1157,7 @@ nsRDFDocument::GetDataBase(nsIRDFDataBase*& result)
NS_IMETHODIMP NS_IMETHODIMP
nsRDFDocument::CreateChildren(nsIRDFContent* element, nsISupportsArray* children) nsRDFDocument::CreateChildren(nsIRDFContent* element)
{ {
nsresult rv; nsresult rv;
@ -1205,24 +1205,16 @@ nsRDFDocument::CreateChildren(nsIRDFContent* element, nsISupportsArray* children
PRBool moreValues; PRBool moreValues;
while (NS_SUCCEEDED(rv = values->HasMoreElements(moreValues)) && moreValues) { while (NS_SUCCEEDED(rv = values->HasMoreElements(moreValues)) && moreValues) {
nsIRDFNode* value = nsnull; nsIRDFNode* value = nsnull;
if (NS_FAILED(rv = values->GetNext(value, tv /* ignored */))) if (NS_SUCCEEDED(rv = values->GetNext(value, tv /* ignored */))) {
break; // At this point, the specific nsRDFDocument
// implementations will create an appropriate child
// XXX At this point, we need to decide exactly what kind // element (or elements).
// of kid to create in the content model. For example, for rv = AddChild(element, property, value);
// leaf nodes, we probably want to create some kind of
// text element.
nsIRDFContent* child;
if (NS_FAILED(rv = CreateChild(property, value, child))) {
NS_RELEASE(value); NS_RELEASE(value);
break;
} }
// And finally, add the child into the content model if (NS_FAILED(rv))
children->AppendElement(child); break;
NS_RELEASE(child);
NS_RELEASE(value);
} }
NS_RELEASE(values); NS_RELEASE(values);

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

@ -194,7 +194,7 @@ public:
NS_IMETHOD Init(void); NS_IMETHOD Init(void);
NS_IMETHOD SetRootResource(nsIRDFNode* resource); NS_IMETHOD SetRootResource(nsIRDFNode* resource);
NS_IMETHOD GetDataBase(nsIRDFDataBase*& result); NS_IMETHOD GetDataBase(nsIRDFDataBase*& result);
NS_IMETHOD CreateChildren(nsIRDFContent* element, nsISupportsArray* children); NS_IMETHOD CreateChildren(nsIRDFContent* element);
NS_IMETHOD AddTreeProperty(nsIRDFNode* resource); NS_IMETHOD AddTreeProperty(nsIRDFNode* resource);
NS_IMETHOD RemoveTreeProperty(nsIRDFNode* resource); NS_IMETHOD RemoveTreeProperty(nsIRDFNode* resource);
@ -214,9 +214,9 @@ protected:
nsIRDFContent*& result, nsIRDFContent*& result,
PRBool childrenMustBeGenerated); PRBool childrenMustBeGenerated);
virtual nsresult CreateChild(nsIRDFNode* property, virtual nsresult AddChild(nsIRDFContent* parent,
nsIRDFNode* value, nsIRDFNode* property,
nsIRDFContent*& result) = 0; nsIRDFNode* value) = 0;
nsIArena* mArena; nsIArena* mArena;
nsVoidArray mObservers; nsVoidArray mObservers;

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

@ -1045,6 +1045,9 @@ nsRDFElement::GetAttributeCount(PRInt32& aResult) const
nsresult rv = NS_OK; nsresult rv = NS_OK;
aResult = 0; aResult = 0;
if (mAttributes)
aResult += mAttributes->Count();
#if defined(CREATE_PROPERTIES_AS_ATTRIBUTES) #if defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
PR_ASSERT(0); // XXX need to write this... PR_ASSERT(0); // XXX need to write this...
#endif // defined(CREATE_PROPERTIES_AS_ATTRIBUTES) #endif // defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
@ -1062,9 +1065,6 @@ rdf_Indent(FILE* out, PRInt32 aIndent)
NS_IMETHODIMP NS_IMETHODIMP
nsRDFElement::List(FILE* out, PRInt32 aIndent) const nsRDFElement::List(FILE* out, PRInt32 aIndent) const
{ {
if (! mResource)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv; nsresult rv;
{ {
@ -1219,9 +1219,12 @@ nsRDFElement::Init(nsIRDFDocument* doc,
PRBool childrenMustBeGenerated) PRBool childrenMustBeGenerated)
{ {
NS_PRECONDITION(doc, "null ptr"); NS_PRECONDITION(doc, "null ptr");
NS_PRECONDITION(resource, "null ptr");
if (!doc || !resource) // XXX Not using this because of a hack in nsRDFTreeDocument: need
// to expose generic XML elements!
//NS_PRECONDITION(resource, "null ptr");
if (!doc /* || !resource // XXX ibid */)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
mTag = aTag; mTag = aTag;
@ -1229,15 +1232,13 @@ nsRDFElement::Init(nsIRDFDocument* doc,
mDocument = doc; // not refcounted mDocument = doc; // not refcounted
mResource = resource; mResource = resource;
NS_ADDREF(mResource); NS_IF_ADDREF(mResource);
mChildrenMustBeGenerated = childrenMustBeGenerated; mChildrenMustBeGenerated = childrenMustBeGenerated;
if (! childrenMustBeGenerated) { nsresult rv;
nsresult rv; if (NS_FAILED(rv = NS_NewISupportsArray(&mChildren)))
if (NS_FAILED(rv = NS_NewISupportsArray(&mChildren))) return rv;
return rv;
}
return NS_OK; return NS_OK;
} }
@ -1383,11 +1384,17 @@ nsRDFElement::GenerateChildren(void) const
unconstThis->mChildren->Clear(); unconstThis->mChildren->Clear();
} }
if (NS_FAILED(rv = mDocument->CreateChildren(unconstThis, // Clear this value *first*, so we can re-enter the nsIContent
unconstThis->mChildren))) // getters if needed.
return rv;
unconstThis->mChildrenMustBeGenerated = PR_FALSE; unconstThis->mChildrenMustBeGenerated = PR_FALSE;
if (NS_FAILED(rv = mDocument->CreateChildren(unconstThis))) {
// Well, maybe it was a transient error. This'll let use try
// again some time in the future.
unconstThis->mChildrenMustBeGenerated = PR_TRUE;
return rv;
}
return NS_OK; return NS_OK;
} }

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

@ -43,9 +43,9 @@ public:
virtual ~RDFHTMLDocumentImpl(); virtual ~RDFHTMLDocumentImpl();
protected: protected:
virtual nsresult CreateChild(nsIRDFNode* property, virtual nsresult AddChild(nsIRDFContent* parent,
nsIRDFNode* value, nsIRDFNode* property,
nsIRDFContent*& result); nsIRDFNode* value);
}; };
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -59,9 +59,9 @@ RDFHTMLDocumentImpl::~RDFHTMLDocumentImpl(void)
} }
nsresult nsresult
RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property, RDFHTMLDocumentImpl::AddChild(nsIRDFContent* parent,
nsIRDFNode* value, nsIRDFNode* property,
nsIRDFContent*& result) nsIRDFNode* value)
{ {
nsresult rv; nsresult rv;
nsIRDFContent* child = nsnull; nsIRDFContent* child = nsnull;
@ -96,9 +96,6 @@ RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property,
if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE))) if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE)))
goto done; goto done;
result = child;
NS_ADDREF(result);
} }
else { else {
// Otherwise, it's not a tree property. So we'll just create a // Otherwise, it's not a tree property. So we'll just create a
@ -115,11 +112,10 @@ RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property,
if (NS_FAILED(rv = AttachTextNode(child, value))) if (NS_FAILED(rv = AttachTextNode(child, value)))
goto done; goto done;
result = child;
NS_ADDREF(result);
} }
rv = parent->AppendChildTo(child, PR_TRUE);
done: done:
NS_IF_RELEASE(child); NS_IF_RELEASE(child);
return rv; return rv;

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

@ -29,15 +29,36 @@
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static const char* kChildrenTag = "CHILDREN";
static const char* kFolderTag = "FOLDER";
static const char* kItemTag = "ITEM";
////////////////////////////////////////////////////////////////////////
class RDFTreeDocumentImpl : public nsRDFDocument { class RDFTreeDocumentImpl : public nsRDFDocument {
public: public:
RDFTreeDocumentImpl(); RDFTreeDocumentImpl();
virtual ~RDFTreeDocumentImpl(); virtual ~RDFTreeDocumentImpl();
protected: protected:
virtual nsresult CreateChild(nsIRDFNode* property, virtual nsresult
nsIRDFNode* value, AddChild(nsIRDFContent* parent,
nsIRDFContent*& result); nsIRDFNode* property,
nsIRDFNode* value);
nsresult
EnsureChildrenElement(nsIContent* parent,
nsIContent*& result);
nsresult
AddTreeChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value);
nsresult
AddPropertyChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value);
}; };
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -50,70 +71,178 @@ RDFTreeDocumentImpl::~RDFTreeDocumentImpl(void)
{ {
} }
nsresult nsresult
RDFTreeDocumentImpl::CreateChild(nsIRDFNode* property, RDFTreeDocumentImpl::EnsureChildrenElement(nsIContent* parent,
nsIRDFNode* value, nsIContent*& result)
nsIRDFContent*& result)
{ {
static const char* kTRTag = "TR"; nsresult rv;
static const char* kTDTag = "TD"; result = nsnull; // reasonable default
nsIAtom* childrenTag = NS_NewAtom(kChildrenTag);
if (! childrenTag)
return NS_ERROR_OUT_OF_MEMORY;
PRInt32 count;
if (NS_FAILED(rv = parent->ChildCount(count))) {
NS_RELEASE(childrenTag);
return rv;
}
for (PRInt32 i = 0; i < count; ++i) {
nsIContent* kid;
if (NS_FAILED(rv = parent->ChildAt(i, kid)))
break;
nsIAtom* tag;
if (NS_FAILED(rv = parent->GetTag(tag))) {
NS_RELEASE(kid);
break;
}
if (tag == childrenTag) {
NS_RELEASE(tag);
NS_RELEASE(childrenTag);
result = kid; // no need to addref, got it from ChildAt().
return NS_OK;
}
NS_RELEASE(tag);
NS_RELEASE(kid);
}
NS_RELEASE(childrenTag);
if (NS_FAILED(rv))
return rv;
// if we get here, we need to construct a new <children> element.
// XXX this should be a generic XML element, not an nsRDFElement
nsIRDFContent* children = nsnull;
if (NS_FAILED(rv = NS_NewRDFElement(&children)))
goto done;
if (NS_FAILED(rv = children->Init(this, kChildrenTag, nsnull /* XXX */, PR_FALSE)))
goto done;
if (NS_FAILED(rv = parent->AppendChildTo(children, PR_FALSE)))
goto done;
result = children;
NS_ADDREF(result);
done:
NS_IF_RELEASE(children);
return rv;
}
nsresult
RDFTreeDocumentImpl::AddTreeChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value)
{
// If it's a tree property, then we need to add the new child
// element to a special "children" element in the parent. The
// child element's value will be the value of the
// property. We'll also attach an "ID=" attribute to the new
// child; e.g.,
//
// <parent>
// ...
// <children>
// <item id="value">
// <!-- recursively generated -->
// </item>
// </children>
// ...
// </parent>
nsresult rv; nsresult rv;
nsIRDFContent* child = nsnull; nsIRDFContent* child = nsnull;
nsIContent* children = nsnull;
nsAutoString s;
if (IsTreeProperty(property) || rdf_IsContainer(mResourceMgr, mDB, value)) { // Ensure that the <children> element exists on the parent.
// If it's a tree property, then create a child element whose if (NS_FAILED(rv = EnsureChildrenElement(parent, children)))
// value is the value of the property. We'll also attach an "ID=" goto done;
// attribute to the new child; e.g.,
//
// <parent>
// <tr id="value">
// <!-- recursively generated -->
// </tr>
// ...
// </parent>
nsAutoString s; // Create a new child that represents the "value"
// resource. PR_TRUE indicates that we want the child to
// dynamically generate its own kids.
if (NS_FAILED(rv = NewChild(kFolderTag, value, child, PR_TRUE)))
goto done;
// PR_TRUE indicates that we want the child to dynamically if (NS_FAILED(rv = value->GetStringValue(s)))
// generate its own kids. goto done;
if (NS_FAILED(rv = NewChild(kTRTag, value, child, PR_TRUE)))
goto done;
if (NS_FAILED(rv = value->GetStringValue(s))) if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE)))
goto done; goto done;
if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE))) #define ALL_NODES_OPEN_HACK
goto done; #ifdef ALL_NODES_OPEN_HACK
if (NS_FAILED(rv = child->SetAttribute("OPEN", "TRUE", PR_FALSE)))
goto done;
#endif
result = child; // Finally, add the thing to the <children> element.
NS_ADDREF(result); children->AppendChildTo(child, PR_TRUE);
}
else {
// Otherwise, it's not a tree property. So we'll just create a
// new element for the property, and a simple text node for
// its value; e.g.,
//
// <parent>
// <td>value</td>
// ...
// </parent>
if (NS_FAILED(rv = NewChild(kTDTag, property, child, PR_FALSE))) done:
goto done; NS_IF_RELEASE(child);
NS_IF_RELEASE(children);
return rv;
}
if (NS_FAILED(rv = AttachTextNode(child, value)))
goto done;
result = child; nsresult
NS_ADDREF(result); RDFTreeDocumentImpl::AddPropertyChild(nsIRDFContent* parent,
} nsIRDFNode* property,
nsIRDFNode* value)
{
// Otherwise, it's not a tree property. So we'll just create a
// new element for the property, and a simple text node for
// its value; e.g.,
//
// <parent>
// <td>value</td>
// ...
// </parent>
nsresult rv;
nsIRDFContent* child = nsnull;
nsAutoString s;
if (NS_FAILED(rv = property->GetStringValue(s)))
goto done;
if (NS_FAILED(rv = NewChild(s, property, child, PR_FALSE)))
goto done;
if (NS_FAILED(rv = AttachTextNode(child, value)))
goto done;
rv = parent->AppendChildTo(child, PR_TRUE);
done: done:
NS_IF_RELEASE(child); NS_IF_RELEASE(child);
return rv; return rv;
} }
nsresult
RDFTreeDocumentImpl::AddChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value)
{
if (IsTreeProperty(property) || rdf_IsContainer(mResourceMgr, mDB, value)) {
return AddTreeChild(parent, property, value);
}
else {
return AddPropertyChild(parent, property, value);
}
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////