📄 abstracttreeviewer.java
字号:
* into grouping by working sets, which requires viewers to support multiple * equal elements. See bug 76482 for more details. This support will * likely be removed in Eclipse 3.2 in favour of proper support for * multiple equal elements. * </p> * * @param widget * the widget * @param element * the element * @param doStruct * <code>true</code> if structural changes are to be picked up, * and <code>false</code> if only label provider changes are of * interest * @param updateLabels * <code>true</code> to update labels for existing elements, * <code>false</code> to only update labels as needed, assuming * that labels for existing elements are unchanged. * @since 3.1 */ protected void internalRefresh(Widget widget, Object element, boolean doStruct, boolean updateLabels) { if (widget instanceof Item) { if (doStruct) { updatePlus((Item) widget, element); } if (updateLabels || !equals(element, widget.getData())) { doUpdateItem(widget, element, true); } else { associate(element, (Item) widget); } } if (doStruct) { internalRefreshStruct(widget, element, updateLabels); } else { Item[] children = getChildren(widget); if (children != null) { for (int i = 0; i < children.length; i++) { Widget item = children[i]; Object data = item.getData(); if (data != null) { internalRefresh(item, data, doStruct, updateLabels); } } } } } /** * Update the structure and recurse. Items are updated in updateChildren, * as needed. * @param widget * @param element * @param updateLabels */ /* package */ void internalRefreshStruct(Widget widget, Object element, boolean updateLabels) { updateChildren(widget, element, null, updateLabels); Item[] children = getChildren(widget); if (children != null) { for (int i = 0; i < children.length; i++) { Widget item = children[i]; Object data = item.getData(); if (data != null) { internalRefreshStruct(item, data, updateLabels); } } } } /** * Removes the given elements from this viewer. * <p> * EXPERIMENTAL. Not to be used except by JDT. * This method was added to support JDT's explorations * into grouping by working sets, which requires viewers to support multiple * equal elements. See bug 76482 for more details. This support will * likely be removed in Eclipse 3.2 in favour of proper support for * multiple equal elements. * </p> * * @param elementsOrPaths * the elements or element paths to remove * @since 3.1 */ protected void internalRemove(Object[] elementsOrPaths) { Object input = getInput(); // Note: do not use the comparer here since the hashtable // contains SWT Items, not model elements. CustomHashtable parentItems = new CustomHashtable(5); for (int i = 0; i < elementsOrPaths.length; ++i) { Object element = elementsOrPaths[i]; if (equals(element, input)) { setInput(null); return; } Widget[] childItems = internalFindItems(element); for (int j = 0; j < childItems.length; j++) { Widget childItem = childItems[j]; if (childItem instanceof Item) { Item parentItem = getParentItem((Item) childItem); if (parentItem != null) { parentItems.put(parentItem, parentItem); } disassociate((Item) childItem); childItem.dispose(); } } } internalReconcileParentItems(parentItems); } /** * @param parentItems */ private void internalReconcileParentItems(CustomHashtable parentItems) { Control tree = getControl(); for (Enumeration e = parentItems.keys(); e.hasMoreElements();) { Item parentItem = (Item) e.nextElement(); if(parentItem.isDisposed()) { continue; } if (!getExpanded(parentItem) && getItemCount(parentItem) == 0) { // append a dummy if necessary if (isExpandable(parentItem, null, parentItem.getData())) { newItem(parentItem, SWT.NULL, -1); } else { // XXX: Workaround (PR missing) tree.redraw(); } } } } /** * Removes the given elements from this viewer, whenever those elements appear as children * of the given parent. * * @param elements * the elements to remove * @since 3.1 */ protected void internalRemove(Object parent, Object[] elements) { CustomHashtable toRemove = new CustomHashtable(getComparer()); for (int i = 0; i < elements.length; i++) { toRemove.put(elements[i], elements[i]); } // Note: do not use the comparer here since the hashtable // contains SWT Items, not model elements. CustomHashtable parentItems = new CustomHashtable(5); // Find each place the parent appears in the tree Widget[] parentItemArray = findItems(parent); for (int i = 0; i < parentItemArray.length; i++) { Widget parentItem = parentItemArray[i]; if (parentItem instanceof Item) { parentItems.put(parentItem, parentItem); } // Iterate over the child items and remove each one Item[] children = getChildren(parentItem); for (int j = 0; j < children.length; j++) { Item child = children[j]; Object data = child.getData(); if (data !=null && toRemove.containsKey(data)) { disassociate(child); child.dispose(); } } } internalReconcileParentItems(parentItems); } /** * Sets the expanded state of all items to correspond to the given set of * expanded elements. * * @param expandedElements * the set (element type: <code>Object</code>) of elements * which are expanded * @param widget * the widget */ private void internalSetExpanded(CustomHashtable expandedElements, Widget widget) { Item[] items = getChildren(widget); for (int i = 0; i < items.length; i++) { Item item = items[i]; Object data = item.getData(); if (data != null) { // remove the element to avoid an infinite loop // if the same element appears on a child item boolean expanded = expandedElements.remove(data) != null; if (expanded != getExpanded(item)) { if (expanded) { createChildren(item); } setExpanded(item, expanded); } } if (expandedElements.size() > 0) { internalSetExpanded(expandedElements, item); } } } /** * Sets the expanded state of all items to correspond to the given set of * expanded tree paths. * * @param expandedTreePaths * the set (element type: <code>TreePath</code>) of elements * which are expanded * @param widget * the widget */ private void internalSetExpandedTreePaths(CustomHashtable expandedTreePaths, Widget widget, TreePath currentPath) { Item[] items = getChildren(widget); for (int i = 0; i < items.length; i++) { Item item = items[i]; Object data = item.getData(); TreePath childPath = data==null ? null: currentPath.createChildPath(data); if (data != null && childPath!=null) { // remove the element to avoid an infinite loop // if the same element appears on a child item boolean expanded = expandedTreePaths.remove(childPath) != null; if (expanded != getExpanded(item)) { if (expanded) { createChildren(item); } setExpanded(item, expanded); } } internalSetExpandedTreePaths(expandedTreePaths, item, childPath); } } /** * Return whether the tree node representing the given element or path can be * expanded. Clients should query expandablity by path if the viewer's * content provider is an {@link ITreePathContentProvider}. * <p> * The default implementation of this framework method calls <code>hasChildren</code> * on this viewer's content provider. It may be overridden if necessary. * </p> * * @param elementOrTreePath * the element or path * @return <code>true</code> if the tree node representing the given * element can be expanded, or <code>false</code> if not */ public boolean isExpandable(Object elementOrTreePath) { Object element; TreePath path; if (elementOrTreePath instanceof TreePath) { path = (TreePath) elementOrTreePath; element = path.getLastSegment(); } else { element = elementOrTreePath; path = null; } IContentProvider cp = getContentProvider(); if (cp instanceof ITreePathContentProvider) { ITreePathContentProvider tpcp = (ITreePathContentProvider) cp; if (path == null) { // A path was not provided so try and find one Widget w = findItem(element); if (w instanceof Item) { Item item = (Item) w; path = getTreePathFromItem(item); } if (path == null) { path = new TreePath(new Object[] { element }); } } return tpcp.hasChildren(path); } if (cp instanceof ITreeContentProvider) { ITreeContentProvider tcp = (ITreeContentProvider) cp; return tcp.hasChildren(element); } return false; } /** * Return whether the given element is expandable. * @param item the tree item for the element * @param parentPath the parent path if it is knwon or <code>null</code> if it needs to be determines * @param element the element * @return whether the given element is expandable */ private boolean isExpandable(Item item, TreePath parentPath, Object element) { if (isTreePathContentProvider()) { TreePath path; if (parentPath != null) { path = parentPath.createChildPath(element); } else { path = getTreePathFromItem(item); } ITreePathContentProvider cp = (ITreePathContentProvider) getContentProvider(); return cp != null && cp.hasChildren(path); } return isExpandable(element); } /* (non-Javadoc) Method declared on Viewer. */ protected void labelProviderChanged() { // we have to walk the (visible) tree and update every item Control tree = getControl(); tree.setRedraw(false); // don't pick up structure changes, but do force label updates internalRefresh(tree, getRoot(), false, true); tree.setRedraw(true); } /** * Creates a new item. * * @param parent * the parent widget * @param style * SWT style bits * @param index * if non-negative, indicates the position to insert the item * into its parent * @return the newly-created item */ protected abstract Item newItem(Widget parent, int style, int index); /** * Removes the given elements from this viewer. The selection is updated if * required. * <p> * This method should be called (by the content provider) when elements * have been removed from the model, in order to cause the viewer to * accurately reflect the model. This method only affects the viewer, not * the model. * </p> * * @param elementsOrTreePaths * the elements to remove */ public void remove(final Object[] elementsOrTreePaths) { assertElementsNotNull(elementsOrTreePaths); if (elementsOrTreePaths.length == 0) { return; } preservingSelection(new Runnable() { public void run() { internalRemove(elementsOrTreePaths); } }); } /** * Removes the given elements from this viewer whenever they appear as children * of the given parent element. If the given elements also appear as children * of some other parent, the other parent will remain unchanged. The selection * is updated if required. * <p> * This method should be called (by the content provider) when elements * have been removed from the model, in order to cause the viewer to * accurately reflect the model. This method only affects the viewer, not * the model. * </p> * * @param parent the parent of the elements to remove * @param elements * the elements to remove * * @since 3.2 */ public void remove(final Object parent, final Object[] elements) { assertElementsNotNull(elements); if (elements.length == 0) { return; } preservingSelection(new Runnable() { public void run() { internalRemove(parent, elements); } }); } /** * Removes the given element from the viewer. The selection is updated if * necess
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -