Refactoring SelectIn action to make it more extensible.

This commit is contained in:
Kirill Maximov
2005-02-15 15:15:09 +03:00
parent e9e091a5c4
commit f45ca10791
9 changed files with 315 additions and 175 deletions
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package com.intellij.ide;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
/**
* @author kir
*/
public interface SelectInContext {
String DATA_CONTEXT_ID = "SelectInContext";
Project getProject();
/** @deprecated */
PsiFile getPsiFile();
/** @deprecated */
PsiElement getPsiElement();
VirtualFile getVirtualFile();
Object getSelectorInFile();
}
@@ -4,22 +4,20 @@
*/
package com.intellij.ide;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
public interface SelectInTarget {
String toString();
/**
* This should be called in an read action
*/
boolean canSelect(PsiFile file);
boolean canSelect(SelectInContext context);
void select(PsiElement element, boolean requestFocus);
void selectIn(SelectInContext context, final boolean requestFocus);
/** Tool window this target is supposed to select in */
String getToolWindowId();
/** aux view id specific for tool window, e.g. Project/Packages/J2EE tab inside project View */
String getMinorViewId();
}
@@ -1,32 +1,37 @@
package com.intellij.ide.actions;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.SelectInContext;
import com.intellij.ide.SelectInManager;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.roots.ui.util.CellAppearanceUtils;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.project.Project;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.ListPopup;
import com.intellij.ui.SimpleTextAttributes;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class SelectInAction extends AnAction {
public void actionPerformed(AnActionEvent e) {
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.select.in");
SelectInContext context = SelectInContext.createContext(e);
SelectInContextImpl.SelectInContextProvider context = SelectInContextImpl.createContext(e);
if (context == null) return;
invoke(context);
}
public void update(AnActionEvent event) {
Presentation presentation = event.getPresentation();
SelectInContext context = SelectInContext.createContext(event);
if (context == null) {
if (SelectInContextImpl.createContext(event) == null) {
presentation.setEnabled(false);
presentation.setVisible(false);
} else {
@@ -35,8 +40,8 @@ public class SelectInAction extends AnAction {
}
}
public void invoke(SelectInContext context) {
final SelectInTarget[] targetVector = context.getTargets();
public void invoke(SelectInContextImpl.SelectInContextProvider contextProvider) {
final SelectInTarget[] targetVector = getTargets(contextProvider.getContext());
final JList list;
final Runnable runnable;
@@ -46,7 +51,7 @@ public class SelectInAction extends AnAction {
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setCellRenderer(new MyListCellRenderer());
runnable = new MyRunnable(context, list);
runnable = new MyRunnable(contextProvider.getContext(), list);
}
else {
list = new JList(new String[] {"No targets available in this context"});
@@ -62,13 +67,56 @@ public class SelectInAction extends AnAction {
" Select Target ",
list,
runnable,
context.getProject()
contextProvider.getContext().getProject()
);
Point p = context.getPoint();
Point p = contextProvider.getInvocationPoint();
listPopup.show(p.x, p.y);
}
protected SelectInTarget[] getTargets(SelectInContext context) {
ArrayList<SelectInTarget> result = getTargetsFor(context);
if (result.size() > 1) {
rearrangeTargetList(context, result);
}
return result.toArray(new SelectInTarget[result.size()]);
}
private ArrayList<SelectInTarget> getTargetsFor(final SelectInContext context) {
ArrayList<SelectInTarget> result = new ArrayList<SelectInTarget>();
final SelectInTarget[] targets = getSelectInManager(context.getProject()).getTargets();
for (int i = 0; i < targets.length; i++) {
SelectInTarget target = targets[i];
if (target.canSelect(context)) {
result.add(target);
}
}
return result;
}
private static SelectInManager getSelectInManager(Project project) {
return SelectInManager.getInstance(project);
}
private void rearrangeTargetList(final SelectInContext context, final ArrayList<SelectInTarget> result) {
final String activeToolWindowId = ToolWindowManager.getInstance(context.getProject()).getActiveToolWindowId();
if (activeToolWindowId != null) {
SelectInTarget firstTarget = result.get(0);
if (activeToolWindowId.equals(firstTarget.getToolWindowId())) {
boolean shouldMoveToBottom = true;
if (ToolWindowId.PROJECT_VIEW.equals(activeToolWindowId)) {
final String currentMinorViewId = ProjectView.getInstance(context.getProject()).getCurrentViewId();
shouldMoveToBottom = (currentMinorViewId != null) && currentMinorViewId.equals(firstTarget.getMinorViewId());
}
if (shouldMoveToBottom) {
result.remove(0);
result.add(firstTarget);
}
}
}
}
private static final class MyListCellRenderer extends ColoredListCellRenderer{
private final SimpleTextAttributes myAttributes;
@@ -102,9 +150,9 @@ public class SelectInAction extends AnAction {
// this can be if you click item with Ctrl pressed
return;
}
SelectInManager selectInManager = myContext.getManager();
SelectInManager selectInManager = getSelectInManager(myContext.getProject());
selectInManager.moveToTop(selected);
myContext.selectIn(selected);
selected.selectIn(myContext, true);
}
}
}
@@ -1,14 +1,11 @@
package com.intellij.ide.actions;
import com.intellij.execution.Location;
import com.intellij.ide.SelectInManager;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.SelectInContext;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataConstants;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.ex.DataConstantsEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -18,8 +15,6 @@ import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
@@ -30,45 +25,49 @@ import com.intellij.util.IJSwingUtilities;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.util.ArrayList;
abstract class SelectInContext {
private final PopupLocation myPopupLocation;
abstract class SelectInContextImpl implements SelectInContext {
private final PsiFile myPsiFile;
protected SelectInContext(PopupLocation popupLocation, PsiFile psiFile) {
myPopupLocation = popupLocation;
protected SelectInContextImpl(PsiFile psiFile) {
myPsiFile = psiFile;
}
public SelectInManager getManager() { return SelectInManager.getInstance(getProject()); }
public Project getProject() { return myPsiFile.getProject(); }
public SelectInTarget[] getTargets() { return getTargets(myPsiFile); }
public Point getPoint() { return myPopupLocation.getPoint(); }
protected PsiFile getPsiFile() { return myPsiFile; }
public abstract void selectIn(SelectInTarget selected);
public PsiFile getPsiFile() { return myPsiFile; }
public VirtualFile getVirtualFile() { return myPsiFile.getVirtualFile(); }
public static SelectInContext createContext(AnActionEvent event) {
public Object getSelectorInFile() {
return getPsiElement();
}
public static SelectInContextProvider createContext(AnActionEvent event) {
DataContext dataContext = event.getDataContext();
SelectInContext result = createEditorContext(dataContext);
SelectInContextProvider result = createEditorContext(dataContext);
if (result != null) return result;
JComponent sourceComponent = getEventComponent(event);
if (sourceComponent == null) return null;
ComponentCenterLocation popupLocation = new ComponentCenterLocation(sourceComponent);
SelectInContext psiContext = createPsiContext(event, popupLocation);
if (psiContext != null) return psiContext;
SelectInContext selectInContext = ((SelectInContext)dataContext.getData(SelectInContext.DATA_CONTEXT_ID));
if (selectInContext == null) {
selectInContext = createPsiContext(event);
}
if (selectInContext == null) {
Navigatable descriptor = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE);
if (!(descriptor instanceof OpenFileDescriptor)) return null;
Navigatable descriptor = (Navigatable)dataContext.getData(DataConstants.NAVIGATABLE);
if (!(descriptor instanceof OpenFileDescriptor)) return null;
Project project = (Project)dataContext.getData(DataConstants.PROJECT);
selectInContext = OpenFileDescriptorContext.create(project, (OpenFileDescriptor)descriptor);
}
Project project = (Project)dataContext.getData(DataConstants.PROJECT);
return OpenFileDescriptorContext.create(project, popupLocation, (OpenFileDescriptor)descriptor);
return new SelectInContextProvider(selectInContext, popupLocation);
}
private static SelectInContext createEditorContext(DataContext dataContext) {
private static SelectInContextProvider createEditorContext(DataContext dataContext) {
final Project project = (Project)dataContext.getData(DataConstants.PROJECT);
final FileEditor editor = (FileEditor)dataContext.getData(DataConstants.FILE_EDITOR);
if (project == null || editor == null) return null;
@@ -76,15 +75,22 @@ abstract class SelectInContext {
if (file == null) return null;
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile == null) return null;
if (editor instanceof TextEditor) {
return new TextEditorContext((TextEditor)editor, psiFile);
return new SelectInContextProvider(
new TextEditorContext((TextEditor)editor, psiFile),
new EditorCaretLocation(((TextEditor)editor).getEditor())
);
}
else {
return new SimpleContext(new ComponentCenterLocation(editor.getComponent()), psiFile);
return new SelectInContextProvider(
new SimpleSelectInContext(psiFile),
new ComponentCenterLocation(editor.getComponent())
);
}
}
private static SelectInContext createPsiContext(AnActionEvent event, PopupLocation popupLocation) {
private static SelectInContext createPsiContext(AnActionEvent event) {
final DataContext dataContext = event.getDataContext();
PsiElement psiElement = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT);
if (psiElement == null || !psiElement.isValid()) {
@@ -94,7 +100,7 @@ abstract class SelectInContext {
if (psiFile == null) {
return null;
}
return new SimpleContext(popupLocation, psiFile, psiElement);
return new SimpleSelectInContext(psiFile, psiElement);
}
private static JComponent getEventComponent(AnActionEvent event) {
@@ -108,33 +114,20 @@ abstract class SelectInContext {
}
}
protected SelectInTarget[] getTargets(PsiFile psiFile) {
ArrayList<SelectInTarget> result = new ArrayList<SelectInTarget>();
final SelectInTarget[] targets = getManager().getTargets();
for (int i = 0; i < targets.length; i++) {
SelectInTarget target = targets[i];
if (target.canSelect(psiFile)) {
result.add(target);
}
static class SelectInContextProvider {
private final SelectInContext myContext;
private final PopupLocation myPopupLocation;
public SelectInContextProvider(SelectInContext context, PopupLocation popupLocation) {
assert context != null : "Null SelectInContext";
assert popupLocation != null : "Null PopupLocation";
myContext = context;
myPopupLocation = popupLocation;
}
if (result.size() > 1) {
final String activeToolWindowId = ToolWindowManager.getInstance(getProject()).getActiveToolWindowId();
if (activeToolWindowId != null) {
SelectInTarget firstTarget = result.get(0);
if (activeToolWindowId.equals(firstTarget.getToolWindowId())) {
boolean shouldMoveToBottom = true;
if (ToolWindowId.PROJECT_VIEW.equals(activeToolWindowId)) {
final String currentMinorViewId = ProjectView.getInstance(getProject()).getCurrentViewId();
shouldMoveToBottom = (currentMinorViewId != null) && currentMinorViewId.equals(firstTarget.getMinorViewId());
}
if (shouldMoveToBottom) {
result.remove(0);
result.add(firstTarget);
}
}
}
}
return result.toArray(new SelectInTarget[result.size()]);
public SelectInContext getContext() { return myContext; }
public Point getInvocationPoint() { return myPopupLocation.getPoint(); }
}
private interface PopupLocation {
@@ -181,49 +174,43 @@ abstract class SelectInContext {
}
}
private static class TextEditorContext extends SelectInContext {
private static class TextEditorContext extends SelectInContextImpl {
private final TextEditor myEditor;
public TextEditorContext(TextEditor editor, PsiFile psiFile) {
super(new EditorCaretLocation(editor.getEditor()), psiFile);
super(psiFile);
myEditor = editor;
}
public void selectIn(final SelectInTarget selected) {
CommandProcessor commandProcessor = CommandProcessor.getInstance();
Runnable runnable = new Runnable() {
public void run() {
PsiElement element = getPsiFile();
Editor editor = myEditor.getEditor();
final int offset = editor.getCaretModel().getOffset();
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
PsiElement e = getPsiFile().findElementAt(offset);
if (e != null) {
element = e;
}
selected.select(element, true);
}
};
commandProcessor.executeCommand(getProject(), runnable, "Select in " + selected, null);
public PsiElement getPsiElement() {
PsiElement element = getPsiFile();
Editor editor = myEditor.getEditor();
final int offset = editor.getCaretModel().getOffset();
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
PsiElement e = getPsiFile().findElementAt(offset);
if (e != null) {
element = e;
}
return element;
}
}
private static class OpenFileDescriptorContext extends SelectInContext {
private static class OpenFileDescriptorContext extends SelectInContextImpl {
private final OpenFileDescriptor myDescriptor;
public OpenFileDescriptorContext(PopupLocation popupLocation, PsiFile psiFile, OpenFileDescriptor descriptor) {
super(popupLocation, psiFile);
public OpenFileDescriptorContext(PsiFile psiFile, OpenFileDescriptor descriptor) {
super(psiFile);
myDescriptor = descriptor;
}
public void selectIn(SelectInTarget selected) {
public PsiElement getPsiElement() {
PsiElement psiElement;
if (myDescriptor.getOffset() >= 0) psiElement = findElementAt(myDescriptor.getOffset());
else {
String text = LoadTextUtil.loadText(myDescriptor.getFile(), new String[1]).toString();
psiElement = findElementAt(StringUtil.lineColToOffset(text, myDescriptor.getLine(), myDescriptor.getColumn()));
}
selected.select(psiElement, true);
return psiElement;
}
private PsiElement findElementAt(int offset) {
@@ -231,30 +218,30 @@ abstract class SelectInContext {
return psiElement != null ? psiElement : getPsiFile();
}
public static SelectInContext create(Project project, PopupLocation popupLocation, OpenFileDescriptor descriptor) {
public static SelectInContext create(Project project, OpenFileDescriptor descriptor) {
if (descriptor == null) return null;
VirtualFile file = descriptor.getFile();
if (file == null || !file.isValid()) return null;
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile == null) return null;
return new OpenFileDescriptorContext(popupLocation, psiFile, descriptor);
return new OpenFileDescriptorContext(psiFile, descriptor);
}
}
private static class SimpleContext extends SelectInContext {
private static class SimpleSelectInContext extends SelectInContextImpl {
private final PsiElement myElementToSelect;
public SimpleContext(PopupLocation popupLocation, PsiFile psiFile) {
this(popupLocation, psiFile, psiFile);
public SimpleSelectInContext(PsiFile psiFile) {
this(psiFile, psiFile);
}
public SimpleContext(PopupLocation popupLocation, PsiFile psiFile, PsiElement elementToSelect) {
super(popupLocation, psiFile);
public SimpleSelectInContext(PsiFile psiFile, PsiElement elementToSelect) {
super(psiFile);
myElementToSelect = elementToSelect;
}
public void selectIn(SelectInTarget selected) {
selected.select(myElementToSelect, true);
public PsiElement getPsiElement() {
return myElementToSelect;
}
}
}
@@ -3,6 +3,7 @@ package com.intellij.ide.commander;
import com.intellij.aspects.psi.PsiAspect;
import com.intellij.aspects.psi.PsiAspectFile;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.SelectInContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
@@ -22,11 +23,11 @@ final class CommanderSelectInTarget implements SelectInTarget {
return "Commander";
}
public boolean canSelect(final PsiFile file) {
private boolean canSelect(final PsiFile file) {
return file.getManager().isInProject(file);
}
public void select(PsiElement element, boolean requestFocus) {
private void select(PsiElement element, boolean requestFocus) {
while (true) {
if (element instanceof PsiFile) {
break;
@@ -65,6 +66,14 @@ final class CommanderSelectInTarget implements SelectInTarget {
}
}
public boolean canSelect(SelectInContext context) {
return canSelect(context.getPsiFile());
}
public void selectIn(SelectInContext context, final boolean requestFocus) {
select(context.getPsiElement(), requestFocus);
}
public String getToolWindowId() {
return ToolWindowId.COMMANDER;
}
@@ -2,6 +2,7 @@ package com.intellij.ide.impl;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.PackageViewPane;
import com.intellij.ide.SelectInContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
@@ -39,6 +40,14 @@ public class PackageViewSelectInTarget extends ProjectViewSelectInTarget {
super.select(element, requestFocus);
}
public boolean canSelect(SelectInContext context) {
return canSelect(context.getPsiFile());
}
public void selectIn(SelectInContext context, final boolean requestFocus) {
select(context.getPsiElement(), requestFocus);
}
private boolean isInLibraryContentOnly(final VirtualFile vFile) {
if (vFile == null) {
return false;
@@ -1,6 +1,7 @@
package com.intellij.ide.impl;
import com.intellij.ide.projectView.impl.ProjectViewPane;
import com.intellij.ide.SelectInContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
@@ -32,6 +33,14 @@ public class ProjectPaneSelectInTarget extends ProjectViewSelectInTarget {
return false;
}
public void selectIn(SelectInContext context, final boolean requestFocus) {
select(context.getPsiElement(), requestFocus);
}
public boolean canSelect(SelectInContext context) {
return canSelect(context.getPsiFile());
}
public String getMinorViewId() {
return ProjectViewPane.ID;
}
@@ -1,6 +1,7 @@
package com.intellij.ide.impl;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.SelectInContext;
import com.intellij.ide.structureView.StructureView;
import com.intellij.ide.structureView.StructureViewFactory;
import com.intellij.openapi.fileEditor.FileEditor;
@@ -28,7 +29,7 @@ public class StructureViewSelectInTarget implements SelectInTarget {
/**
* This is called in an atomic action
*/
public boolean canSelect(PsiFile file) {
private boolean canSelect(PsiFile file) {
StructureView structureView = getStructureView();
if (file == null) {
return false;
@@ -41,7 +42,7 @@ public class StructureViewSelectInTarget implements SelectInTarget {
}
}
public void select(PsiElement element, final boolean requestFocus) {
private void select(PsiElement element, final boolean requestFocus) {
PsiElement targetElement = element;
while (true) {
if (targetElement instanceof PsiClass && !(targetElement instanceof PsiAnonymousClass)) break;
@@ -71,6 +72,14 @@ public class StructureViewSelectInTarget implements SelectInTarget {
}
}
public boolean canSelect(SelectInContext context) {
return canSelect(context.getPsiFile());
}
public void selectIn(SelectInContext context, final boolean requestFocus) {
select(context.getPsiElement(), requestFocus);
}
private StructureView getStructureView() {
return StructureViewFactory.getInstance(myProject).getStructureView();
}
@@ -6,9 +6,9 @@ import com.intellij.ide.projectView.BaseProjectTreeBuilder;
import com.intellij.ide.projectView.HelpID;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.nodes.PackageElement;
import com.intellij.ide.projectView.impl.nodes.PackageElementNode;
import com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.projectView.impl.nodes.PackageElementNode;
import com.intellij.ide.util.DeleteHandler;
import com.intellij.ide.util.EditorHelper;
import com.intellij.ide.util.treeView.AbstractTreeNode;
@@ -149,74 +149,8 @@ public final class ProjectViewImpl extends ProjectView implements JDOMExternaliz
setAutoscrollToSource(state, myCurrentViewId);
}
};
myAutoScrollFromSourceHandler = new AutoScrollFromSourceHandler(myProject) {
private Alarm myAlarm = new Alarm();
private FileEditorManagerAdapter myEditorManagerListener;
public void install() {
myEditorManagerListener = new FileEditorManagerAdapter() {
public void selectionChanged(final FileEditorManagerEvent event) {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
public void run() {
if(myProject.isDisposed()) return;
if (isAutoscrollFromSource(getCurrentViewId())) {
FileEditor newEditor = event.getNewEditor();
if (newEditor instanceof TextEditor) {
Editor editor = ((TextEditor)newEditor).getEditor();
selectElementAtCaretNotLosingFocus(editor);
}
}
}
}, 400);
}
};
FileEditorManager.getInstance(myProject).addFileEditorManagerListener(myEditorManagerListener);
}
private void selectElementAtCaretNotLosingFocus(Editor editor) {
if (IJSwingUtilities.hasFocus(getCurrentProjectViewPane().getComponentToFocus())) return;
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
if (file == null) return;
final SelectInTarget[] targets = SelectInManager.getInstance(myProject).getTargets();
for (int i = 0; i < targets.length; i++) {
SelectInTarget target = targets[i];
if (!ToolWindowId.PROJECT_VIEW.equals(target.getToolWindowId())) continue;
String compatiblePaneViewId = target.getMinorViewId();
if (!Comparing.strEqual(compatiblePaneViewId, getCurrentViewId())) continue;
if (!target.canSelect(file)) continue;
final int offset = editor.getCaretModel().getOffset();
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
PsiElement e = file.findElementAt(offset);
if (e == null) {
e = file;
}
target.select(e, false);
break;
}
}
public void dispose() {
if (myEditorManagerListener != null) {
FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myEditorManagerListener);
}
}
protected boolean isAutoScrollMode() {
return isAutoscrollFromSource(myCurrentViewId);
}
protected void setAutoScrollMode(boolean state) {
setAutoscrollFromSource(state, myCurrentViewId);
if (state) {
final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
if (editor != null) {
selectElementAtCaretNotLosingFocus(editor);
}
}
}
};
myAutoScrollFromSourceHandler = new MyAutoScrollFromSourceHandler();
}
public void disposeComponent() {
@@ -1172,4 +1106,113 @@ public final class ProjectViewImpl extends ProjectView implements JDOMExternaliz
public void selectModuleGroup(ModuleGroup moduleGroup, boolean b) {
}
private class MyAutoScrollFromSourceHandler extends AutoScrollFromSourceHandler {
private Alarm myAlarm = new Alarm();
private FileEditorManagerAdapter myEditorManagerListener;
public MyAutoScrollFromSourceHandler() {
super(ProjectViewImpl.this.myProject);
}
public void install() {
myEditorManagerListener = new FileEditorManagerAdapter() {
public void selectionChanged(final FileEditorManagerEvent event) {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
public void run() {
if(myProject.isDisposed()) return;
if (isAutoscrollFromSource(getCurrentViewId())) {
FileEditor newEditor = event.getNewEditor();
if (newEditor instanceof TextEditor) {
Editor editor = ((TextEditor)newEditor).getEditor();
selectElementAtCaretNotLosingFocus(editor);
}
}
}
}, 400);
}
};
FileEditorManager.getInstance(myProject).addFileEditorManagerListener(myEditorManagerListener);
}
private void selectElementAtCaretNotLosingFocus(final Editor editor) {
if (IJSwingUtilities.hasFocus(getCurrentProjectViewPane().getComponentToFocus())) return;
final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
if (file == null) return;
final MySelectInContext selectInContext = new MySelectInContext(file, editor);
final SelectInTarget[] targets = SelectInManager.getInstance(myProject).getTargets();
for (int i = 0; i < targets.length; i++) {
SelectInTarget target = targets[i];
if (!ToolWindowId.PROJECT_VIEW.equals(target.getToolWindowId())) continue;
String compatiblePaneViewId = target.getMinorViewId();
if (!Comparing.strEqual(compatiblePaneViewId, getCurrentViewId())) continue;
if (!target.canSelect(selectInContext)) continue;
target.selectIn(selectInContext, false);
break;
}
}
public void dispose() {
if (myEditorManagerListener != null) {
FileEditorManager.getInstance(myProject).removeFileEditorManagerListener(myEditorManagerListener);
}
}
protected boolean isAutoScrollMode() {
return isAutoscrollFromSource(myCurrentViewId);
}
protected void setAutoScrollMode(boolean state) {
setAutoscrollFromSource(state, myCurrentViewId);
if (state) {
final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
if (editor != null) {
selectElementAtCaretNotLosingFocus(editor);
}
}
}
private class MySelectInContext implements SelectInContext {
private final PsiFile myPsiFile;
private final Editor myEditor;
public MySelectInContext(final PsiFile psiFile, Editor editor) {
myPsiFile = psiFile;
myEditor = editor;
}
public Project getProject() {
return getPsiFile().getProject();
}
public PsiFile getPsiFile() {
return myPsiFile;
}
public PsiElement getPsiElement() {
final int offset = myEditor.getCaretModel().getOffset();
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
PsiElement e = getPsiFile().findElementAt(offset);
if (e == null) {
e = getPsiFile();
}
return e;
}
public VirtualFile getVirtualFile() {
return getPsiFile().getVirtualFile();
}
public Object getSelectorInFile() {
return getPsiElement();
}
}
}
}