986 lines
23 KiB
C++
986 lines
23 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
#include "nsHTMLTokens.h"
|
|
#include "nsXPFCXMLDTD.h"
|
|
#include "nsxpfcCIID.h"
|
|
#include "nsIXMLParserObject.h"
|
|
#include "nsXPFCXMLContentSink.h"
|
|
#include "nsIXPFCMenuBar.h"
|
|
#include "nsIXPFCMenuItem.h"
|
|
#include "nsIXPFCMenuContainer.h"
|
|
#include "nsIXPFCCanvas.h"
|
|
#include "nsIButton.h"
|
|
#include "nsITextWidget.h"
|
|
#include "nsITabWidget.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsXPFCToolkit.h"
|
|
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID);
|
|
static NS_DEFINE_IID(kClassIID, NS_XPFCXMLCONTENTSINK_IID);
|
|
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
|
|
static NS_DEFINE_IID(kIXMLParserObjectIID, NS_IXML_PARSER_OBJECT_IID);
|
|
static NS_DEFINE_IID(kCXPFCMenuBarCID, NS_XPFCMENUBAR_CID);
|
|
static NS_DEFINE_IID(kCXPFCMenuItemCID, NS_XPFCMENUITEM_CID);
|
|
static NS_DEFINE_IID(kCXPFCMenuContainerCID, NS_XPFCMENUCONTAINER_CID);
|
|
static NS_DEFINE_IID(kCIXPFCMenuBarIID, NS_IXPFCMENUBAR_IID);
|
|
static NS_DEFINE_IID(kCIXPFCMenuItemIID, NS_IXPFCMENUITEM_IID);
|
|
static NS_DEFINE_IID(kCIXPFCMenuContainerIID, NS_IXPFCMENUCONTAINER_IID);
|
|
static NS_DEFINE_IID(kCXPFCToolbarCID, NS_XPFC_TOOLBAR_CID);
|
|
static NS_DEFINE_IID(kCIXPFCToolbarIID, NS_IXPFC_TOOLBAR_IID);
|
|
static NS_DEFINE_IID(kCXPFCDialogCID, NS_XPFC_DIALOG_CID);
|
|
static NS_DEFINE_IID(kCIXPFCDialogIID, NS_IXPFC_DIALOG_IID);
|
|
static NS_DEFINE_IID(kCXPFCCanvasCID, NS_XPFC_CANVAS_CID);
|
|
static NS_DEFINE_IID(kIXPFCCanvasIID, NS_IXPFC_CANVAS_IID);
|
|
static NS_DEFINE_IID(kCButtonCID, NS_BUTTON_CID);
|
|
static NS_DEFINE_IID(kCTextWidgetCID, NS_TEXTFIELD_CID);
|
|
static NS_DEFINE_IID(kCTabWidgetCID, NS_TABWIDGET_CID);
|
|
static NS_DEFINE_IID(kCXPFCButtonCID, NS_XPFC_BUTTON_CID);
|
|
static NS_DEFINE_IID(kCXPButtonCID, NS_XP_BUTTON_CID);
|
|
static NS_DEFINE_IID(kCXPFCTabWidgetCID, NS_XPFC_TABWIDGET_CID);
|
|
static NS_DEFINE_IID(kCXPFCTextWidgetCID, NS_XPFC_TEXTWIDGET_CID);
|
|
static NS_DEFINE_IID(kIXPFCXMLContentSinkIID, NS_IXPFC_XML_CONTENT_SINK_IID);
|
|
static NS_DEFINE_IID(kIXPFCContentSinkIID, NS_IXPFC_CONTENT_SINK_IID);
|
|
|
|
#define XPFC_PARSING_STATE_UNKNOWN 0
|
|
#define XPFC_PARSING_STATE_TOOLBAR 1
|
|
#define XPFC_PARSING_STATE_MENUBAR 2
|
|
#define XPFC_PARSING_STATE_DIALOG 3
|
|
#define XPFC_PARSING_STATE_APPLICATION 4
|
|
|
|
class ContainerListEntry {
|
|
public:
|
|
nsIXMLParserObject * object;
|
|
nsString container;
|
|
|
|
ContainerListEntry(nsIXMLParserObject * aObject,
|
|
nsString aContainer) {
|
|
object = aObject;
|
|
container = aContainer;
|
|
}
|
|
~ContainerListEntry() {
|
|
}
|
|
};
|
|
|
|
|
|
nsXPFCXMLContentSink::nsXPFCXMLContentSink() : nsIHTMLContentSink()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mViewerContainer = nsnull;
|
|
mContainerList = nsnull;
|
|
|
|
mState = XPFC_PARSING_STATE_UNKNOWN;
|
|
|
|
static NS_DEFINE_IID(kCVectorCID, NS_ARRAY_CID);
|
|
nsresult res = nsRepository::CreateInstance(kCVectorCID,
|
|
nsnull,
|
|
kCVectorCID,
|
|
(void **)&mOrphanMenuList);
|
|
|
|
if (NS_OK != res)
|
|
return ;
|
|
|
|
mOrphanMenuList->Init();
|
|
|
|
static NS_DEFINE_IID(kCStackCID, NS_STACK_CID);
|
|
|
|
res = nsRepository::CreateInstance(kCStackCID,
|
|
nsnull,
|
|
kCStackCID,
|
|
(void **)&mXPFCStack);
|
|
|
|
if (NS_OK != res)
|
|
return ;
|
|
|
|
mXPFCStack->Init();
|
|
|
|
if (mContainerList == nsnull) {
|
|
|
|
static NS_DEFINE_IID(kCVectorIteratorCID, NS_ARRAY_ITERATOR_CID);
|
|
static NS_DEFINE_IID(kCVectorCID, NS_ARRAY_CID);
|
|
|
|
nsresult res = nsRepository::CreateInstance(kCVectorCID,
|
|
nsnull,
|
|
kCVectorCID,
|
|
(void **)&mContainerList);
|
|
|
|
if (NS_OK != res)
|
|
return ;
|
|
|
|
mContainerList->Init();
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
nsXPFCXMLContentSink::~nsXPFCXMLContentSink()
|
|
{
|
|
NS_RELEASE(mOrphanMenuList);
|
|
NS_RELEASE(mXPFCStack);
|
|
|
|
if (mContainerList != nsnull) {
|
|
|
|
nsIIterator * iterator;
|
|
|
|
mContainerList->CreateIterator(&iterator);
|
|
iterator->Init();
|
|
|
|
ContainerListEntry * item;
|
|
|
|
while(!(iterator->IsDone()))
|
|
{
|
|
item = (ContainerListEntry *) iterator->CurrentItem();
|
|
delete item;
|
|
iterator->Next();
|
|
}
|
|
NS_RELEASE(iterator);
|
|
|
|
mContainerList->RemoveAll();
|
|
NS_RELEASE(mContainerList);
|
|
}
|
|
|
|
}
|
|
|
|
NS_IMPL_ADDREF(nsXPFCXMLContentSink)
|
|
NS_IMPL_RELEASE(nsXPFCXMLContentSink)
|
|
|
|
|
|
nsresult nsXPFCXMLContentSink::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|
{
|
|
if (NULL == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
|
*aInstancePtr = (nsIContentSink*)(this);
|
|
}
|
|
else if(aIID.Equals(kIContentSinkIID)) { //do nsIContentSink base class...
|
|
*aInstancePtr = (nsIContentSink*)(this);
|
|
}
|
|
else if(aIID.Equals(kIHTMLContentSinkIID)) {
|
|
*aInstancePtr = (nsIHTMLContentSink*)(this);
|
|
}
|
|
else if(aIID.Equals(kClassIID)) { //do this class...
|
|
*aInstancePtr = (nsXPFCXMLContentSink*)(this);
|
|
}
|
|
else if(aIID.Equals(kIXPFCXMLContentSinkIID)) { //do this class...
|
|
*aInstancePtr = (nsIXPFCXMLContentSink*)(this);
|
|
}
|
|
else if(aIID.Equals(kIXPFCContentSinkIID)) { //do this class...
|
|
*aInstancePtr = (nsIXPFCContentSink*)(this);
|
|
}
|
|
else {
|
|
*aInstancePtr=0;
|
|
return NS_NOINTERFACE;
|
|
}
|
|
((nsISupports*) *aInstancePtr)->AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::Init()
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
* this method gets invoked whenever a container type tag
|
|
* is encountered.
|
|
*/
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenContainer(const nsIParserNode& aNode)
|
|
{
|
|
nsIXMLParserObject * object = nsnull;
|
|
eXPFCXMLTags tag = (eXPFCXMLTags) aNode.GetNodeType();
|
|
nsresult res;
|
|
nsCID aclass;
|
|
nsString toLoadUrl;
|
|
|
|
if (eXPFCXMLTag_menubar == tag)
|
|
mState = XPFC_PARSING_STATE_MENUBAR;
|
|
else if (eXPFCXMLTag_toolbar == tag)
|
|
mState = XPFC_PARSING_STATE_TOOLBAR;
|
|
else if (eXPFCXMLTag_dialog == tag)
|
|
mState = XPFC_PARSING_STATE_DIALOG;
|
|
else if (eXPFCXMLTag_application == tag)
|
|
mState = XPFC_PARSING_STATE_APPLICATION;
|
|
|
|
if (mState == XPFC_PARSING_STATE_APPLICATION)
|
|
{
|
|
if (eXPFCXMLTag_canvas == tag)
|
|
{
|
|
PRInt32 i = 0;
|
|
nsString key,value;
|
|
|
|
for (i = 0; i < aNode.GetAttributeCount(); i++)
|
|
{
|
|
|
|
key = aNode.GetKeyAt(i);
|
|
value = aNode.GetValueAt(i);
|
|
|
|
key.StripChars("\"");
|
|
value.StripChars("\"");
|
|
|
|
if (key.EqualsIgnoreCase("src"))
|
|
{
|
|
// Load the url!
|
|
toLoadUrl = value;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
//return NS_OK;
|
|
}
|
|
|
|
nsString text = aNode.GetText();
|
|
|
|
res = CIDFromTag(tag, aclass);
|
|
|
|
if (NS_OK != res)
|
|
return res ;
|
|
|
|
res = nsRepository::CreateInstance(aclass,
|
|
nsnull,
|
|
kIXMLParserObjectIID,
|
|
(void **)&object);
|
|
|
|
if (NS_OK != res)
|
|
return res ;
|
|
|
|
|
|
/*
|
|
* ConsumeAttributes
|
|
*/
|
|
|
|
AddToHierarchy(*object, PR_TRUE);
|
|
object->Init();
|
|
ConsumeAttributes(aNode,*object);
|
|
|
|
/*
|
|
* If this is a menu bar, tell the widget.
|
|
* Probably want a general notification scheme for menubar
|
|
* changes
|
|
*/
|
|
|
|
if (eXPFCXMLTag_menubar == tag)
|
|
{
|
|
nsIXPFCMenuBar * menubar;
|
|
res = object->QueryInterface(kCIXPFCMenuBarIID,(void**)&menubar);
|
|
|
|
if (NS_OK == res)
|
|
{
|
|
mViewerContainer->SetMenuBar(menubar);
|
|
NS_RELEASE(menubar);
|
|
}
|
|
}
|
|
/*
|
|
* If this is a menu bar, tell the widget.
|
|
* Probably want a general notification scheme for menubar
|
|
* changes
|
|
*/
|
|
|
|
if (eXPFCXMLTag_toolbar == tag)
|
|
{
|
|
|
|
nsIXPFCToolbar * toolbar;
|
|
res = object->QueryInterface(kCIXPFCToolbarIID,(void**)&toolbar);
|
|
|
|
if (NS_OK == res)
|
|
{
|
|
mViewerContainer->AddToolbar(toolbar);
|
|
NS_RELEASE(toolbar);
|
|
}
|
|
|
|
}
|
|
|
|
if (eXPFCXMLTag_dialog == tag)
|
|
{
|
|
|
|
nsIXPFCDialog * dialog;
|
|
res = object->QueryInterface(kCIXPFCDialogIID,(void**)&dialog);
|
|
|
|
if (NS_OK == res)
|
|
{
|
|
mViewerContainer->ShowDialog(dialog);
|
|
NS_RELEASE(dialog);
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* If this was a root panel, add it to the widget
|
|
*/
|
|
|
|
if (eXPFCXMLTag_application == tag)
|
|
{
|
|
nsIXPFCCanvas * child = (nsIXPFCCanvas *) mXPFCStack->Top();
|
|
|
|
if (child != nsnull)
|
|
{
|
|
nsIXPFCCanvas * root ;
|
|
|
|
gXPFCToolkit->GetRootCanvas(&root);
|
|
|
|
root->DeleteChildren();
|
|
|
|
root->AddChildCanvas(child);
|
|
|
|
NS_RELEASE(root);
|
|
}
|
|
}
|
|
|
|
if (toLoadUrl.Length() > 0)
|
|
{
|
|
nsIXPFCCanvas * canvas = nsnull;
|
|
|
|
if (toLoadUrl.Find(".cal") != -1)
|
|
object->QueryInterface(kIXPFCCanvasIID,(void**)&canvas);
|
|
|
|
mViewerContainer->LoadURL(toLoadUrl,nsnull,canvas);
|
|
|
|
NS_IF_RELEASE(canvas);
|
|
}
|
|
|
|
NS_RELEASE(object);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseContainer(const nsIParserNode& aNode)
|
|
{
|
|
nsISupports * container = (nsISupports *)mXPFCStack->Pop();
|
|
|
|
/*
|
|
* If we popped the topmost canvas, lay it out
|
|
*/
|
|
|
|
nsISupports * parent = (nsISupports *) mXPFCStack->Top();
|
|
if (parent == nsnull && container != nsnull)
|
|
{
|
|
nsIXPFCCanvas * canvas ;
|
|
nsresult res = container->QueryInterface(kIXPFCCanvasIID,(void**)&canvas);
|
|
|
|
if (res == NS_OK)
|
|
{
|
|
canvas->Layout();
|
|
NS_RELEASE(canvas);
|
|
}
|
|
}
|
|
|
|
NS_IF_RELEASE(container);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::AddLeaf(const nsIParserNode& aNode)
|
|
{
|
|
nsIXMLParserObject * object = nsnull;
|
|
eXPFCXMLTags tag = (eXPFCXMLTags) aNode.GetNodeType();
|
|
nsresult res;
|
|
nsCID aclass;
|
|
|
|
// XXX Til we implement separators
|
|
if (tag == eXPFCXMLTag_separator)
|
|
return NS_OK;
|
|
|
|
/*
|
|
* The XML may specify this as a leaf, but it's parameters
|
|
* will reference a child object, in which case it's
|
|
* runtime is a container
|
|
*/
|
|
|
|
if (IsContainer(aNode) == PR_TRUE)
|
|
{
|
|
res = OpenContainer(aNode);
|
|
CloseContainer(aNode);
|
|
return res;
|
|
}
|
|
|
|
|
|
nsString text = aNode.GetText();
|
|
|
|
res = CIDFromTag(tag, aclass);
|
|
|
|
|
|
res = nsRepository::CreateInstance(aclass,
|
|
nsnull,
|
|
kIXMLParserObjectIID,
|
|
(void **)&object);
|
|
|
|
if (NS_OK != res)
|
|
return res ;
|
|
|
|
AddToHierarchy(*object, PR_FALSE);
|
|
|
|
object->Init();
|
|
|
|
ConsumeAttributes(aNode,*object);
|
|
|
|
// XXX: Need a way to identify that native widgets are
|
|
// involved!
|
|
if (tag == eXPFCXMLTag_button
|
|
|| tag == eXPFCXMLTag_tabwidget
|
|
|| tag == eXPFCXMLTag_editfield)
|
|
{
|
|
nsIXPFCCanvas * canvas = nsnull;
|
|
res = object->QueryInterface(kIXPFCCanvasIID,(void**)&canvas);
|
|
if (NS_OK == res)
|
|
{
|
|
canvas->CreateView();
|
|
NS_RELEASE(canvas);
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(object);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::PushMark()
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenHTML(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseHTML(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenHead(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseHead(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::SetTitle(const nsString& aValue)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenBody(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseBody(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenForm(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseForm(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenMap(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseMap(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::OpenFrameset(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CloseFrameset(const nsIParserNode& aNode)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::WillBuildModel(void)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
|
{
|
|
|
|
if (mState == XPFC_PARSING_STATE_MENUBAR)
|
|
{
|
|
nsIIterator * iterator;
|
|
|
|
mContainerList->CreateIterator(&iterator);
|
|
|
|
iterator->Init();
|
|
|
|
ContainerListEntry * item ;
|
|
|
|
while(!(iterator->IsDone()))
|
|
{
|
|
item = (ContainerListEntry *) iterator->CurrentItem();
|
|
|
|
/*
|
|
* item->object is the parent container
|
|
* item->container is the name of the target child container
|
|
*
|
|
* There should be a nsIXPFCMenuContainer in the free list with this
|
|
* name. Let's find it, make it the child, and remove from free list
|
|
*/
|
|
|
|
nsIIterator * iterator2 ;
|
|
nsIXPFCMenuContainer * menu_container;
|
|
nsString child;
|
|
nsIXPFCMenuItem * container_item = nsnull;
|
|
|
|
|
|
nsresult res = mOrphanMenuList->CreateIterator(&iterator2);
|
|
|
|
if (NS_OK != res)
|
|
return nsnull;
|
|
|
|
iterator2->Init();
|
|
|
|
while(!(iterator2->IsDone()))
|
|
{
|
|
menu_container = (nsIXPFCMenuContainer *) iterator2->CurrentItem();
|
|
|
|
|
|
res = menu_container->QueryInterface(kCIXPFCMenuItemIID,(void**)&container_item);
|
|
|
|
if (res == NS_OK)
|
|
{
|
|
|
|
child = container_item->GetName();
|
|
|
|
if (child == item->container) {
|
|
|
|
/*
|
|
* Set as child
|
|
*/
|
|
|
|
nsIXPFCMenuContainer * parent = nsnull;
|
|
res = item->object->QueryInterface(kCIXPFCMenuContainerIID, (void**)&parent);
|
|
|
|
if (res == NS_OK)
|
|
{
|
|
parent->AddChild((nsIXPFCMenuItem *)container_item);
|
|
NS_RELEASE(parent);
|
|
}
|
|
|
|
mOrphanMenuList->Remove(child);
|
|
NS_RELEASE(container_item);
|
|
break;
|
|
}
|
|
|
|
NS_RELEASE(container_item);
|
|
|
|
}
|
|
|
|
iterator2->Next();
|
|
}
|
|
|
|
|
|
NS_RELEASE(iterator2);
|
|
|
|
iterator->Next();
|
|
}
|
|
|
|
NS_IF_RELEASE(iterator);
|
|
|
|
mViewerContainer->UpdateMenuBar();
|
|
} else if (mState == XPFC_PARSING_STATE_TOOLBAR)
|
|
{
|
|
mViewerContainer->UpdateToolbars();
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::WillInterrupt(void)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::WillResume(void)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult nsXPFCXMLContentSink::SetViewerContainer(nsIWebViewerContainer * aViewerContainer)
|
|
{
|
|
mViewerContainer = aViewerContainer;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
* Find the CID from the XML Tag Object
|
|
*/
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::CIDFromTag(eXPFCXMLTags tag, nsCID &aClass)
|
|
{
|
|
switch(tag)
|
|
{
|
|
case eXPFCXMLTag_menuitem:
|
|
aClass = kCXPFCMenuItemCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_menucontainer:
|
|
aClass = kCXPFCMenuContainerCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_menubar:
|
|
aClass = kCXPFCMenuBarCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_toolbar:
|
|
aClass = kCXPFCToolbarCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_dialog:
|
|
aClass = kCXPFCDialogCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_application:
|
|
case eXPFCXMLTag_canvas:
|
|
case eXPFCXMLTag_separator:
|
|
aClass = kCXPFCCanvasCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_editfield:
|
|
aClass = kCXPFCTextWidgetCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_button:
|
|
aClass = kCXPFCButtonCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_xpbutton:
|
|
aClass = kCXPButtonCID;
|
|
break;
|
|
|
|
case eXPFCXMLTag_tabwidget:
|
|
aClass = kCXPFCTabWidgetCID;
|
|
break;
|
|
|
|
default:
|
|
return (NS_ERROR_UNEXPECTED);
|
|
break;
|
|
}
|
|
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::ConsumeAttributes(const nsIParserNode& aNode, nsIXMLParserObject& aObject)
|
|
{
|
|
PRInt32 i = 0;
|
|
nsString key,value;
|
|
nsString scontainer;
|
|
PRBool container = PR_FALSE;
|
|
|
|
for (i = 0; i < aNode.GetAttributeCount(); i++) {
|
|
|
|
key = aNode.GetKeyAt(i);
|
|
value = aNode.GetValueAt(i);
|
|
|
|
key.StripChars("\"");
|
|
value.StripChars("\"");
|
|
|
|
aObject.SetParameter(key,value);
|
|
|
|
if (key.EqualsIgnoreCase(XPFC_STRING_CONTAINER)) {
|
|
container = PR_TRUE;
|
|
scontainer = value;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
eXPFCXMLTags tag = (eXPFCXMLTags) aNode.GetNodeType();
|
|
|
|
//if (container == PR_TRUE)
|
|
// aObject.SetParameter(nsString("popup"),nsString("popup"));
|
|
|
|
/*
|
|
* If this object has something it wants to control, store away the string and source
|
|
* object. Later on, we'll walk the content tree Registering appropriate subjects
|
|
* and observers.
|
|
*/
|
|
|
|
if (container == PR_TRUE)
|
|
{
|
|
mContainerList->Append(new ContainerListEntry(&aObject, scontainer));
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
PRBool nsXPFCXMLContentSink::IsContainer(const nsIParserNode& aNode)
|
|
{
|
|
PRInt32 i = 0;
|
|
nsString key;
|
|
PRBool container = PR_FALSE;
|
|
|
|
for (i = 0; i < aNode.GetAttributeCount(); i++) {
|
|
|
|
key = aNode.GetKeyAt(i);
|
|
key.StripChars("\"");
|
|
|
|
if (key.EqualsIgnoreCase(XPFC_STRING_CONTAINER)) {
|
|
container = PR_TRUE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return container;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsXPFCXMLContentSink::AddToHierarchy(nsIXMLParserObject& aObject, PRBool aPush)
|
|
{
|
|
|
|
if (mState == XPFC_PARSING_STATE_TOOLBAR)
|
|
{
|
|
|
|
nsIXPFCToolbar * container = nsnull;
|
|
nsIXPFCCanvas * parent = nsnull;
|
|
nsIXPFCCanvas * child_canvas = nsnull;
|
|
|
|
aObject.QueryInterface(kIXPFCCanvasIID,(void**)&child_canvas);
|
|
|
|
nsresult res = aObject.QueryInterface(kCIXPFCToolbarIID,(void**)&container);
|
|
|
|
parent = (nsIXPFCCanvas *) mXPFCStack->Top();
|
|
|
|
if (parent == nsnull)
|
|
{
|
|
mViewerContainer->GetToolbarManager()->AddToolbar(container);
|
|
|
|
} else {
|
|
|
|
if (child_canvas != nsnull)
|
|
{
|
|
parent->AddChildCanvas(child_canvas);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (aPush == PR_TRUE)
|
|
PushComponent(child_canvas);
|
|
|
|
NS_IF_RELEASE(child_canvas);
|
|
NS_IF_RELEASE(container);
|
|
|
|
return NS_OK;
|
|
|
|
} else if (mState == XPFC_PARSING_STATE_MENUBAR)
|
|
{
|
|
|
|
nsIXPFCMenuContainer * container = nsnull;
|
|
nsIXPFCMenuContainer * parent = nsnull;
|
|
|
|
nsresult res = aObject.QueryInterface(kCIXPFCMenuContainerIID,(void**)&container);
|
|
|
|
parent = (nsIXPFCMenuContainer *) mXPFCStack->Top();
|
|
|
|
if (NS_OK != res)
|
|
{
|
|
|
|
/*
|
|
* Must be a menu item. Add as child to top of stack
|
|
*/
|
|
nsIXPFCMenuItem * item = nsnull;
|
|
|
|
aObject.QueryInterface(kCIXPFCMenuItemIID,(void**)&item);
|
|
|
|
parent->AddChild(item);
|
|
|
|
item->SetMenuID(mViewerContainer->GetMenuManager()->GetID());
|
|
item->SetReceiver(mViewerContainer->GetMenuManager()->GetDefaultReceiver());
|
|
|
|
NS_RELEASE(item);
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
if (res == NS_OK && parent != nsnull)
|
|
{
|
|
nsIXPFCMenuItem * item = nsnull;
|
|
|
|
nsresult res = aObject.QueryInterface(kCIXPFCMenuItemIID,(void**)&item);
|
|
|
|
parent->AddChild(item);
|
|
|
|
item->SetMenuID(mViewerContainer->GetMenuManager()->GetID());
|
|
item->SetReceiver(mViewerContainer->GetMenuManager()->GetDefaultReceiver());
|
|
|
|
NS_RELEASE(item);
|
|
}
|
|
|
|
if (parent == nsnull)
|
|
{
|
|
/*
|
|
* Add all toplevel menucontainer's to the menu manager
|
|
*/
|
|
|
|
mViewerContainer->GetMenuManager()->AddMenuContainer(container);
|
|
|
|
/*
|
|
* We probably can get rid of the orphanlist now that we
|
|
* have a menu manager.
|
|
*/
|
|
|
|
mOrphanMenuList->Append(container);
|
|
|
|
|
|
}
|
|
|
|
if (aPush == PR_TRUE)
|
|
PushComponent(container);
|
|
|
|
|
|
container->Release();
|
|
|
|
return NS_OK;
|
|
} else if (mState == XPFC_PARSING_STATE_DIALOG)
|
|
{
|
|
|
|
nsIXPFCDialog * container = nsnull;
|
|
nsIXPFCDialog * parent = nsnull;
|
|
|
|
nsresult res = aObject.QueryInterface(kCIXPFCDialogIID,(void**)&container);
|
|
|
|
parent = (nsIXPFCDialog *) mXPFCStack->Top();
|
|
|
|
if (parent == nsnull)
|
|
{
|
|
//mViewerContainer->GetToolbarManager()->AddDialog(container);
|
|
|
|
if (aPush == PR_TRUE)
|
|
PushComponent(container);
|
|
|
|
} else {
|
|
|
|
nsIXPFCCanvas * parent_canvas = nsnull;
|
|
nsIXPFCCanvas * child_canvas = nsnull;
|
|
|
|
res = aObject.QueryInterface(kIXPFCCanvasIID,(void**)&child_canvas);
|
|
|
|
if (NS_OK == res)
|
|
{
|
|
res = parent->QueryInterface(kIXPFCCanvasIID,(void**)&parent_canvas);
|
|
|
|
if (NS_OK == res)
|
|
{
|
|
parent_canvas->AddChildCanvas(child_canvas);
|
|
NS_RELEASE(parent_canvas);
|
|
}
|
|
|
|
if (aPush == PR_TRUE)
|
|
PushComponent(child_canvas);
|
|
|
|
NS_RELEASE(child_canvas);
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
} else if (mState == XPFC_PARSING_STATE_APPLICATION)
|
|
{
|
|
|
|
nsIXPFCCanvas * container = nsnull;
|
|
nsIXPFCCanvas * parent = nsnull;
|
|
|
|
nsresult res = aObject.QueryInterface(kIXPFCCanvasIID,(void**)&container);
|
|
|
|
parent = (nsIXPFCCanvas *) mXPFCStack->Top();
|
|
|
|
if (parent != nsnull)
|
|
parent->AddChildCanvas(container);
|
|
|
|
if (aPush == PR_TRUE)
|
|
PushComponent(container);
|
|
|
|
NS_RELEASE(container);
|
|
|
|
return NS_OK;
|
|
|
|
} else {
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult nsXPFCXMLContentSink::SetContentSinkContainer(nsISupports *
|
|
aContentSinkContainer)
|
|
{
|
|
nsresult res;
|
|
nsIXPFCCanvas * canvas;
|
|
static NS_DEFINE_IID(kIXPFCCanvasIID, NS_IXPFC_CANVAS_IID);
|
|
res = aContentSinkContainer->QueryInterface(kIXPFCCanvasIID, (void **)&canvas);
|
|
if (NS_OK == res)
|
|
{
|
|
res = SetRootCanvas(canvas);
|
|
NS_RELEASE(canvas);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
nsresult nsXPFCXMLContentSink::SetRootCanvas(nsIXPFCCanvas * aCanvas)
|
|
{
|
|
PushComponent(aCanvas);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsXPFCXMLContentSink::PushComponent(nsISupports* aComponent)
|
|
{
|
|
mXPFCStack->Push(aComponent);
|
|
NS_ADDREF(aComponent);
|
|
return NS_OK;
|
|
}
|