From f45ca107912e7ae5940110cd92f986a3b6a32fbd Mon Sep 17 00:00:00 2001 From: Kirill Maximov Date: Tue, 15 Feb 2005 15:15:09 +0300 Subject: [PATCH] Refactoring SelectIn action to make it more extensible. --- .../src/com/intellij/ide/SelectInContext.java | 28 +++ .../src/com/intellij/ide/SelectInTarget.java | 8 +- .../intellij/ide/actions/SelectInAction.java | 70 +++++-- ...nContext.java => SelectInContextImpl.java} | 161 ++++++++-------- .../commander/CommanderSelectInTarget.java | 13 +- .../ide/impl/PackageViewSelectInTarget.java | 9 + .../ide/impl/ProjectPaneSelectInTarget.java | 9 + .../ide/impl/StructureViewSelectInTarget.java | 13 +- .../ide/projectView/impl/ProjectViewImpl.java | 179 +++++++++++------- 9 files changed, 315 insertions(+), 175 deletions(-) create mode 100644 openapi/src/com/intellij/ide/SelectInContext.java rename source/com/intellij/ide/actions/{SelectInContext.java => SelectInContextImpl.java} (54%) diff --git a/openapi/src/com/intellij/ide/SelectInContext.java b/openapi/src/com/intellij/ide/SelectInContext.java new file mode 100644 index 000000000000..23456aaaef10 --- /dev/null +++ b/openapi/src/com/intellij/ide/SelectInContext.java @@ -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(); +} diff --git a/openapi/src/com/intellij/ide/SelectInTarget.java b/openapi/src/com/intellij/ide/SelectInTarget.java index b5b56b540c5c..2d3abdae5dba 100644 --- a/openapi/src/com/intellij/ide/SelectInTarget.java +++ b/openapi/src/com/intellij/ide/SelectInTarget.java @@ -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(); + } diff --git a/source/com/intellij/ide/actions/SelectInAction.java b/source/com/intellij/ide/actions/SelectInAction.java index 4cbf31379be7..4f8392d44c2c 100644 --- a/source/com/intellij/ide/actions/SelectInAction.java +++ b/source/com/intellij/ide/actions/SelectInAction.java @@ -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 result = getTargetsFor(context); + + if (result.size() > 1) { + rearrangeTargetList(context, result); + } + return result.toArray(new SelectInTarget[result.size()]); + } + + private ArrayList getTargetsFor(final SelectInContext context) { + ArrayList result = new ArrayList(); + 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 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); } } } \ No newline at end of file diff --git a/source/com/intellij/ide/actions/SelectInContext.java b/source/com/intellij/ide/actions/SelectInContextImpl.java similarity index 54% rename from source/com/intellij/ide/actions/SelectInContext.java rename to source/com/intellij/ide/actions/SelectInContextImpl.java index 273f6076e586..9af75ace2fd8 100644 --- a/source/com/intellij/ide/actions/SelectInContext.java +++ b/source/com/intellij/ide/actions/SelectInContextImpl.java @@ -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 result = new ArrayList(); - 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; } } } diff --git a/source/com/intellij/ide/commander/CommanderSelectInTarget.java b/source/com/intellij/ide/commander/CommanderSelectInTarget.java index 59a254ada0e0..8e9a0c55fb6b 100644 --- a/source/com/intellij/ide/commander/CommanderSelectInTarget.java +++ b/source/com/intellij/ide/commander/CommanderSelectInTarget.java @@ -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; } diff --git a/source/com/intellij/ide/impl/PackageViewSelectInTarget.java b/source/com/intellij/ide/impl/PackageViewSelectInTarget.java index a05e2c95b562..40ba051c4107 100644 --- a/source/com/intellij/ide/impl/PackageViewSelectInTarget.java +++ b/source/com/intellij/ide/impl/PackageViewSelectInTarget.java @@ -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; diff --git a/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java b/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java index b314bf9abadd..8b4841eaea78 100644 --- a/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java +++ b/source/com/intellij/ide/impl/ProjectPaneSelectInTarget.java @@ -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; } diff --git a/source/com/intellij/ide/impl/StructureViewSelectInTarget.java b/source/com/intellij/ide/impl/StructureViewSelectInTarget.java index ec68f498df02..6b722798f892 100644 --- a/source/com/intellij/ide/impl/StructureViewSelectInTarget.java +++ b/source/com/intellij/ide/impl/StructureViewSelectInTarget.java @@ -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(); } diff --git a/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 6249b6d80990..065830f42239 100644 --- a/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/source/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -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(); + } + } + } }