/******************************************************************************* * Copyright (c) 2000, 2008 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Juerg Billeter, juergbi@ethz.ch - 47136 Search view should show match objects * Ulrich Etter, etteru@ethz.ch - 47136 Search view should show match objects * Roman Fuchs, fuchsro@ethz.ch - 47136 Search view should show match objects *******************************************************************************/ package com.aptana.ide.search.epl.filesystem.ui.text; import java.io.File; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.search.internal.ui.text.IFileSearchContentProvider; import com.aptana.ide.search.epl.FileSearchQuery; import com.aptana.ide.search.epl.FileSystemSearchResult; /** * @author Pavel Petrochenko */ public class FileTreeContentProvider implements ITreeContentProvider, IFileSearchContentProvider { private final Object[] EMPTY_ARR = new Object[0]; private FileSystemSearchResult fResult; private FileSystemSearchPage fPage; private AbstractTreeViewer fTreeViewer; private Map fChildrenMap; FileTreeContentProvider(FileSystemSearchPage page, AbstractTreeViewer viewer) { this.fPage = page; this.fTreeViewer = viewer; } /** * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ public Object[] getElements(Object inputElement) { Object[] children = this.getChildren(inputElement); int elementLimit = this.getElementLimit(); if ((elementLimit != -1) && (elementLimit < children.length)) { Object[] limitedChildren = new Object[elementLimit]; System.arraycopy(children, 0, limitedChildren, 0, elementLimit); return limitedChildren; } return children; } private int getElementLimit() { Integer elementLimit = this.fPage.getElementLimit1(); if (elementLimit!=null){ return elementLimit.intValue(); } return -1; } /** * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ public void dispose() { // nothing to do } /** * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, * java.lang.Object) */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (newInput instanceof FileSystemSearchResult) { this.initialize((FileSystemSearchResult) newInput); } } private synchronized void initialize(FileSystemSearchResult result) { this.fResult = result; this.fChildrenMap = new HashMap(); if (result != null) { Object[] elements = result.getElements(); for (int i = 0; i < elements.length; i++) { //{ this.insert(elements[i], false); //} } } } private void insert(Object child, boolean refreshViewer) { Object parent = this.getParent(child); while (parent != null) { if (this.insertChild(parent, child)) { if (refreshViewer) { this.fTreeViewer.add(parent, child); } } else { if (refreshViewer) { this.fTreeViewer.refresh(parent); } return; } child = parent; parent = this.getParent(child); } if (this.insertChild(this.fResult, child)) { if (refreshViewer) { this.fTreeViewer.add(this.fResult, child); } } } /** * returns true if the child already was a child of parent. * * @param parent * @param child * @return Returns <code>trye</code> if the child was added */ private boolean insertChild(Object parent, Object child) { Set children = (Set) this.fChildrenMap.get(parent); if (children == null) { children = new HashSet(); this.fChildrenMap.put(parent, children); } return children.add(child); } // private boolean hasChild(Object parent, Object child) // { // Set children = (Set) this.fChildrenMap.get(parent); // return (children != null) && children.contains(child); // } private void remove(Object element, boolean refreshViewer) { // precondition here: fResult.getMatchCount(child) <= 0 if (this.hasChildren(element)) { if (refreshViewer) { this.fTreeViewer.refresh(element); } } else { if (!this.hasMatches(element)) { this.fChildrenMap.remove(element); Object parent = this.getParent(element); if (parent != null) { this.removeFromSiblings(element, parent); this.remove(parent, refreshViewer); } else { this.removeFromSiblings(element, this.fResult); if (refreshViewer) { this.fTreeViewer.refresh(); } } } else { if (refreshViewer) { this.fTreeViewer.refresh(element); } } } } private boolean hasMatches(Object element) { return this.fResult.getMatchCount(element) > 0; } private void removeFromSiblings(Object element, Object parent) { Set siblings = (Set) this.fChildrenMap.get(parent); if (siblings != null) { siblings.remove(element); } } /** * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ public Object[] getChildren(Object parentElement) { Set children = (Set) this.fChildrenMap.get(parentElement); if (children == null) { return this.EMPTY_ARR; } return children.toArray(); } /** * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) */ public boolean hasChildren(Object element) { return this.getChildren(element).length > 0; } /** * @see com.aptana.ide.search.epl.filesystem.ui.text.IFileSearchContentProvider#elementsChanged(java.lang.Object[]) */ public synchronized void elementsChanged(Object[] updatedElements) { for (int i = 0; i < updatedElements.length; i++) { if (this.fResult.getMatchCount(updatedElements[i]) > 0) { this.insert(updatedElements[i], true); } else { this.remove(updatedElements[i], true); } } } /** * @see com.aptana.ide.search.epl.filesystem.ui.text.IFileSearchContentProvider#clear() */ public void clear() { this.initialize(this.fResult); this.fTreeViewer.refresh(); } /** * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ public Object getParent(Object element) { if (element instanceof File) { File file = ((File) element); if (file.getAbsolutePath().equals(((FileSearchQuery) this.fResult.getQuery()).getDirectory())) { return null; } return file.getParentFile(); } return null; } }