blob: 22e05a53c02aeb8dac2a83fb39d058b3d6445dec [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.hierarchy;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.TreeBuilderUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.StatusBarProgress;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.FileStatusListener;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiTreeChangeAdapter;
import com.intellij.psi.PsiTreeChangeEvent;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class HierarchyTreeBuilder extends AbstractTreeBuilder {
HierarchyTreeBuilder(@NotNull Project project,
final JTree tree,
final DefaultTreeModel treeModel,
final HierarchyTreeStructure treeStructure,
final Comparator<NodeDescriptor> comparator) {
super(tree, treeModel, treeStructure, comparator);
initRootNode();
PsiManager.getInstance(project).addPsiTreeChangeListener(new MyPsiTreeChangeListener(), this);
FileStatusManager.getInstance(project).addFileStatusListener(new MyFileStatusListener(), this);
}
@NotNull
public Pair<List<Object>, List<Object>> storeExpandedAndSelectedInfo() {
List<Object> pathsToExpand = new ArrayList<Object>();
List<Object> selectionPaths = new ArrayList<Object>();
TreeBuilderUtil.storePaths(this, getRootNode(), pathsToExpand, selectionPaths, true);
return Pair.create(pathsToExpand, selectionPaths);
}
public final void restoreExpandedAndSelectedInfo(@NotNull Pair<List<Object>, List<Object>> pair) {
TreeBuilderUtil.restorePaths(this, pair.first, pair.second, true);
}
@Override
protected boolean isAlwaysShowPlus(final NodeDescriptor nodeDescriptor) {
return ((HierarchyTreeStructure) getTreeStructure()).isAlwaysShowPlus();
}
@Override
protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
return getTreeStructure().getRootElement().equals(nodeDescriptor.getElement())
|| !(nodeDescriptor instanceof HierarchyNodeDescriptor);
}
@Override
protected final boolean isSmartExpand() {
return false;
}
@Override
protected final boolean isDisposeOnCollapsing(final NodeDescriptor nodeDescriptor) {
return false; // prevents problems with building descriptors for invalidated elements
}
private MyStatusBarProgress myProgress;
@Override
@NotNull
protected ProgressIndicator createProgressIndicator() {
return myProgress = new MyStatusBarProgress();
}
public void setProgressIndicator(@NotNull ProgressIndicator indicator) {
myProgress.setSecondaryIndicator(indicator);
}
private static class MyStatusBarProgress extends StatusBarProgress {
private ProgressIndicator mySecondaryIndicator;
public void setSecondaryIndicator(ProgressIndicator indicator) {
mySecondaryIndicator = indicator;
}
@Override
public boolean isCanceled() {
return super.isCanceled() || mySecondaryIndicator != null && mySecondaryIndicator.isCanceled();
}
}
private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter {
@Override
public final void childAdded(@NotNull final PsiTreeChangeEvent event) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
@Override
public final void childRemoved(@NotNull final PsiTreeChangeEvent event) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
@Override
public final void childReplaced(@NotNull final PsiTreeChangeEvent event) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
@Override
public final void childMoved(@NotNull final PsiTreeChangeEvent event) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
@Override
public final void childrenChanged(@NotNull final PsiTreeChangeEvent event) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
@Override
public final void propertyChanged(@NotNull final PsiTreeChangeEvent event) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
}
private final class MyFileStatusListener implements FileStatusListener {
@Override
public final void fileStatusesChanged() {
getUpdater().addSubtreeToUpdate(getRootNode());
}
@Override
public final void fileStatusChanged(@NotNull final VirtualFile virtualFile) {
getUpdater().addSubtreeToUpdate(getRootNode());
}
}
}