[157430] [outline] dtd outline view does not update when delete attribute
diff --git a/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDTreeContentProvider.java b/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDTreeContentProvider.java index a6aa906..d399acb 100644 --- a/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDTreeContentProvider.java +++ b/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDTreeContentProvider.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2001, 2006 IBM Corporation and others. + * Copyright (c) 2001, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -149,53 +149,10 @@ } public Object getParent(Object element) { + List parents = getParents(element); Object parent = null; - if (element instanceof DTDNode) { - DTDNode node = (DTDNode) element; - if (element instanceof Attribute) { - // then we must say that the element with the same name - // as our attribute's parent attributelist is our parent - parent = node.getParentNode(); - if (parent != null && parent instanceof AttributeList) { - return getParent(parent); - } - } - if (element instanceof AttributeList) { - // then we must say that the element with the same name - // as our attributelist is our parent - String attListName = ((AttributeList) element).getName(); - Iterator iter = node.getDTDFile().getElementsAndParameterEntityReferences().getNodes().iterator(); - while (iter.hasNext() && parent == null) { - DTDNode currentNode = (DTDNode) iter.next(); - if (currentNode instanceof Element && currentNode.getName().equals(attListName)) { - parent = currentNode; - } - } - } - - if (parent == null) { - parent = ((DTDNode) element).getParentNode(); - } - - // if showing in the logical order, return the IndexedNodeList - // acting as the parent in the tree - if (parent == null) { - if (isShowLogicalOrder()) { - Object[] indexedNodeLists = getChildren(((DTDModelImpl) fInputObject).getDTDFile()); - for (int i = 0; i < indexedNodeLists.length && parent == null; i++) { - if (indexedNodeLists[i] instanceof NodeList) { - if (((NodeList) indexedNodeLists[i]).getNodes().contains(element)) - parent = indexedNodeLists[i]; - } - } - } - else { - parent = ((DTDModelImpl) fInputObject).getDTDFile(); - } - } - } - else if (element instanceof NodeList && fInputObject instanceof DTDModelImpl) { - parent = ((DTDModelImpl) fInputObject).getDTDFile(); + if(parents.size() > 0) { + parent = parents.get(0); } return parent; } @@ -242,66 +199,13 @@ return true;// !nodeList.getListType().equals(DTDRegionTypes.ATTLIST_TAG); } + /** + * <p>If a node changed then refresh the tree for that node</p> + * + * @see org.eclipse.wst.dtd.core.internal.event.IDTDFileListener#nodeChanged(org.eclipse.wst.dtd.core.internal.DTDNode) + */ public void nodeChanged(final DTDNode node) { - if (fViewer instanceof StructuredViewer) { - // System.out.println("node changed notified"); - // System.out.println("selection before = " + - // ((StructuredViewer)view).getSelection()); - if (node instanceof AttributeList && isShowLogicalOrder()) { - // in this case, we are showing attributes under the element. - // refresh the element object instead - Iterator iter = node.getDTDFile().getNodes().iterator(); - while (iter.hasNext()) { - DTDNode currentNode = (DTDNode) iter.next(); - if (currentNode.getName().equals(node.getName()) && currentNode instanceof Element) { - ((StructuredViewer) fViewer).refresh(currentNode, true); - } - } // end of while () - } - else { - // do standard stuff - fViewer.getControl().getDisplay().asyncExec(new Runnable() { - public void run() { - if (fViewer.getControl().isDisposed()) - return; - if (node.getParentNode() != null) { - ((StructuredViewer) fViewer).refresh(node.getParentNode(), true); - } - ((StructuredViewer) fViewer).refresh(node, true); - } - }); - } - - if (node instanceof Attribute) { - fViewer.getControl().getDisplay().asyncExec(new Runnable() { - public void run() { - if (fViewer.getControl().isDisposed()) - return; - /* - * go from the attribute to its list and then owning element - * so we refresh the tree item there as well - */ - Object attrList = node.getParentNode(); - if (attrList != null && attrList instanceof AttributeList) { - String attListName = ((AttributeList) attrList).getName(); - Iterator iter = node.getDTDFile().getElementsAndParameterEntityReferences().getNodes().iterator(); - Object parent = null; - while (iter.hasNext() && parent == null) { - DTDNode currentNode = (DTDNode) iter.next(); - if (currentNode instanceof Element && currentNode.getName().equals(attListName)) { - parent = currentNode; - } - } - if (parent != null) { - ((StructuredViewer) fViewer).refresh(parent, true); - } - } - } - }); - } - // System.out.println("selection after = " + - // ((StructuredViewer)view).getSelection()); - } + refreshTree(node); } public void nodesAdded(NodesEvent event) { @@ -315,45 +219,8 @@ oldSelectedNode = (DTDNode) firstObj; } - final AbstractTreeViewer abstractTreeViewer = (AbstractTreeViewer) fViewer; - for (Iterator it = event.getNodes().iterator(); it.hasNext();) { - Object node = it.next(); - final Object parent = getParent(node); - // Bug 111100 - If it is a top level node (ie. parent is a - // DTDFile), - // insert the node directly to improve performance - if (parent instanceof DTDFile) { - Object[] objs = getChildren(parent); - for (int i = 0; i < objs.length; i++) { - if (objs[i] == node) { - abstractTreeViewer.insert(parent, node, i); - break; - } - } - } - // If the parent node is not a DTDFile, just refresh the - // parent for now - else if (parent != null) { - fViewer.getControl().getDisplay().asyncExec(new Runnable() { - public void run() { - if (fViewer.getControl().isDisposed()) - return; - abstractTreeViewer.refresh(parent, true); - } - }); - } - // You should never reach this block, if you do, just refresh - // the whole tree - else { - fViewer.getControl().getDisplay().asyncExec(new Runnable() { - public void run() { - if (fViewer.getControl().isDisposed()) - return; - abstractTreeViewer.refresh(true); - } - }); - } - } + //update the tree + refreshTree(event); Iterator iter = event.getNodes().iterator(); List newSelection = new ArrayList(); @@ -380,6 +247,8 @@ } } + //update the tree + refreshTree(event); } /** @@ -395,4 +264,139 @@ logicalNodeLists = null; } } + + /** + * <p>Used to update the tree after a node event such as a node added or removed.</p> + * @param event the {@link NodesEvent} that caused the tree to need updating + */ + private void refreshTree(NodesEvent event) { + for (Iterator it = event.getNodes().iterator(); it.hasNext();) { + Object node = it.next(); + this.refreshTree(node); + + } + } + + /** + * <p>Refreshes the tree from the parents of the given node.</p> + * @param node refresh the tree from the parents of this node + */ + private void refreshTree(Object node) { + List parents = getParents(node); + if(parents.size() > 0) { + for(int p = 0; p < parents.size(); ++p) { + final Object parent = parents.get(p); + + // Bug 111100 - If it is a top level node (ie. parent is a + // DTDFile), + // insert the node directly to improve performance + if (parent instanceof DTDFile) { + Object[] objs = getChildren(parent); + for (int i = 0; i < objs.length; i++) { + if (objs[i] == node) { + ((AbstractTreeViewer) fViewer).insert(parent, node, i); + break; + } + } + } + + this.refreshTreeNode(parent, true); + } + } + } + + /** + * @param element get the tree parents of this element + * @return {@link List} of parents of the given element + */ + private List getParents(Object element) { + List parents = new ArrayList(); + + Object parent = null; + if (element instanceof DTDNode) { + DTDNode node = (DTDNode) element; + if (element instanceof Attribute) { + parent = node.getParentNode(); + if (parent != null && parent instanceof AttributeList) { + parents.addAll(getElementParentsOfAttributeList((AttributeList)parent)); + } + } else if(element instanceof AttributeList) { + parents.addAll(getElementParentsOfAttributeList((AttributeList)element)); + } + + // if showing in the logical order, return the IndexedNodeList + // acting as a parent in the tree + if (isShowLogicalOrder()) { + Object[] indexedNodeLists = getChildren(((DTDModelImpl) fInputObject).getDTDFile()); + for (int i = 0; i < indexedNodeLists.length && parent == null; i++) { + if (indexedNodeLists[i] instanceof NodeList) { + if (((NodeList) indexedNodeLists[i]).getNodes().contains(element)) { + parents.add(indexedNodeLists[i]); + } + } + } + } + + //try and get the simple parent + parent = ((DTDNode) element).getParentNode(); + if(parent != null) { + parents.add(parent); + } + + //if no parents found must be new nodes so refresh from root + if(parents.size() == 0) { + parents.add(((DTDModelImpl) fInputObject).getDTDFile()); + } + }else if (element instanceof NodeList && fInputObject instanceof DTDModelImpl) { + parents.add(((DTDModelImpl) fInputObject).getDTDFile()); + } + + return parents; + } + + /** + * @param attList get the element parents of the given {@link AttributeList} + * @return the element parents of the given {@link AttributeList}, if no parents + * can be found the list contains the DTD file element + */ + private List getElementParentsOfAttributeList(AttributeList attList) { + List parents = new ArrayList(); + Iterator iterAttList = attList.getDTDFile().getNodes().iterator(); + while (iterAttList.hasNext()) { + DTDNode currentNode = (DTDNode) iterAttList.next(); + if (currentNode instanceof Element && + currentNode.getName().equals(attList.getName())) { + + parents.add(currentNode); + } + } + + if(parents.size() == 0) { + parents.add(((DTDModelImpl) fInputObject).getDTDFile()); + } + + return parents; + } + + /** + * <p>Executes a refresh on the {@link AbstractTreeViewer} for the given + * node</p> + * + * @param node refresh the tree for this node + * @param updateLabels <code>true</code> to update the labels on the tree, + * <code>false</code> otherwise. + */ + private void refreshTreeNode(final Object node, final boolean updateLabels) { + fViewer.getControl().getDisplay().asyncExec(new Runnable() { + public void run() { + if (!fViewer.getControl().isDisposed()) { + if(node != null) { + ((AbstractTreeViewer) fViewer).refresh(node, updateLabels); + } else { + ((AbstractTreeViewer) fViewer).refresh(updateLabels); + } + } + } + }); + } }