mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PSI viewer dialog somewhat enhanced
This commit is contained in:
@@ -26,9 +26,7 @@
|
||||
<constraints>
|
||||
<splitpane position="left"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
</properties>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
@@ -57,9 +55,7 @@
|
||||
<constraints>
|
||||
<splitpane position="left"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
</properties>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
@@ -68,9 +64,7 @@
|
||||
<constraints>
|
||||
<splitpane position="right"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
</properties>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
@@ -80,20 +74,19 @@
|
||||
</grid>
|
||||
</children>
|
||||
</splitpane>
|
||||
<grid id="a4d7" layout-manager="GridLayoutManager" row-count="1" column-count="7" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="a4d7" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="85961" class="javax.swing.JCheckBox" binding="myShowWhiteSpacesBox">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<selected value="true"/>
|
||||
<text value="Show Psi&WhiteSpace"/>
|
||||
@@ -101,45 +94,17 @@
|
||||
</component>
|
||||
<component id="88f36" class="javax.swing.JCheckBox" binding="myShowTreeNodesCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<selected value="true"/>
|
||||
<text value="Show Tree &Nodes"/>
|
||||
<text value="Show tree &nodes"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="73b46" class="javax.swing.JComboBox" binding="myDialectsComboBox">
|
||||
<constraints>
|
||||
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="b08f6" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<iconTextGap value="0"/>
|
||||
<text value="Show &PSI structure for:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="3a7d8" binding="myButtonPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusCycleRoot value="true"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="6039a" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="5" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -148,7 +113,7 @@
|
||||
<constraints border-constraint="West"/>
|
||||
<properties>
|
||||
<labelFor value="baf2a"/>
|
||||
<text value="Extension:"/>
|
||||
<text value="E&xtension:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="baf2a" class="javax.swing.JComboBox" binding="myExtensionComboBox">
|
||||
@@ -157,11 +122,49 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<hspacer id="88604">
|
||||
<grid id="77ead" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="6" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="69754" class="com.intellij.ui.components.JBLabel" binding="myDialectLabel">
|
||||
<constraints border-constraint="West"/>
|
||||
<properties>
|
||||
<labelFor value="91e46"/>
|
||||
<text value="&Dialect:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="91e46" class="javax.swing.JComboBox" binding="myDialectComboBox">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="dd04d" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="f146a" class="javax.swing.JLabel">
|
||||
<constraints border-constraint="West"/>
|
||||
<properties>
|
||||
<iconTextGap value="0"/>
|
||||
<labelFor value="383b1"/>
|
||||
<text value="Show &PSI structure for:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="383b1" class="javax.swing.JComboBox" binding="myFileTypeComboBox">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties>
|
||||
<maximumRowCount value="30"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.intellij.internal.psiView;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageUtil;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
@@ -35,7 +38,6 @@ import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.*;
|
||||
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -53,10 +55,8 @@ import com.intellij.psi.impl.source.resolve.FileContextUtil;
|
||||
import com.intellij.psi.search.FilenameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.SortedComboBoxModel;
|
||||
import com.intellij.ui.TitledBorderWithMnemonic;
|
||||
import com.intellij.ui.TreeSpeedSearch;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -64,7 +64,6 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -83,36 +82,36 @@ import java.util.regex.Pattern;
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
private static final String REFS_CACHE = "References Resolve Cache";
|
||||
private static final Color SELECTION_BG_COLOR = Registry.getColor("psi.viewer.selection.color", new Color(255, 204, 204));
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
private final Tree myTree;
|
||||
private final ViewerTreeBuilder myTreeBuilder;
|
||||
|
||||
private final JList myRefs;
|
||||
private static final String REFS_CACHE = "References Resolve Cache";
|
||||
|
||||
private EditorEx myEditor;
|
||||
private String myLastParsedText = null;
|
||||
|
||||
private JCheckBox myShowWhiteSpacesBox;
|
||||
private JPanel myStructureTreePanel;
|
||||
private JPanel myTextPanel;
|
||||
private JPanel myPanel;
|
||||
private JComboBox myFileTypeComboBox;
|
||||
private JCheckBox myShowWhiteSpacesBox;
|
||||
private JCheckBox myShowTreeNodesCheckBox;
|
||||
private JComboBox myDialectsComboBox;
|
||||
private JBLabel myDialectLabel;
|
||||
private JComboBox myDialectComboBox;
|
||||
private JLabel myExtensionLabel;
|
||||
private JComboBox myExtensionComboBox;
|
||||
private JPanel myTextPanel;
|
||||
private JPanel myStructureTreePanel;
|
||||
private JPanel myReferencesPanel;
|
||||
private JPanel myButtonPanel;
|
||||
private JSplitPane myTextSplit;
|
||||
private JSplitPane myTreeSplit;
|
||||
private JComboBox myExtensionComboBox;
|
||||
private JLabel myExtensionLabel;
|
||||
private final Presentation myPresentation = new Presentation();
|
||||
private final Map<String, Object> handlers = new HashMap<String, Object>();
|
||||
private DefaultActionGroup myGroup;
|
||||
private Language[] myLanguageDialects;
|
||||
private final Color SELECTION_BG_COLOR = Registry.getColor("psi.viewer.selection.color", new Color(255, 204, 204));
|
||||
private Tree myTree;
|
||||
private ViewerTreeBuilder myTreeBuilder;
|
||||
private JList myRefs;
|
||||
|
||||
public static class ExtensionComparator implements Comparator<String> {
|
||||
private final Set<SourceWrapper> mySourceWrappers = Sets.newTreeSet();
|
||||
private EditorEx myEditor;
|
||||
private final EditorListener myEditorListener = new EditorListener();
|
||||
private String myLastParsedText = null;
|
||||
private int myLastParsedTextHashCode = 17;
|
||||
private int myNewDocumentHashCode = 11;
|
||||
|
||||
private static class ExtensionComparator implements Comparator<String> {
|
||||
private final String myOnTop;
|
||||
|
||||
public ExtensionComparator(String onTop) {
|
||||
@@ -123,34 +122,66 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
public int compare(String o1, String o2) {
|
||||
if (o1.equals(myOnTop)) return -1;
|
||||
if (o2.equals(myOnTop)) return 1;
|
||||
return o1.compareTo(o2);
|
||||
return o1.compareToIgnoreCase(o2);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Comparator<Language> DIALECTS_COMPARATOR = new Comparator<Language>() {
|
||||
public int compare(final Language o1, final Language o2) {
|
||||
if (o1 == null) return o2 == null ? 0 : -1;
|
||||
if (o2 == null) return 1;
|
||||
return o1.getID().compareTo(o2.getID());
|
||||
}
|
||||
};
|
||||
private final EditorListener myEditorListener = new EditorListener();
|
||||
private int myLastParsedTextHashCode = 17;
|
||||
private int myNewDocumentHashCode = 11;
|
||||
private static class DialectsComparator implements Comparator<Language> {
|
||||
private final Language myDefault;
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findCommonParent(PsiElement start, PsiElement end) {
|
||||
final TextRange range = end.getTextRange();
|
||||
while (start != null && !start.getTextRange().contains(range)) {
|
||||
start = start.getParent();
|
||||
public DialectsComparator(final Language aDefault) {
|
||||
myDefault = aDefault;
|
||||
}
|
||||
|
||||
public int compare(final Language o1, final Language o2) {
|
||||
if (myDefault.equals(o1)) return -1;
|
||||
if (myDefault.equals(o2)) return 1;
|
||||
return o1.getID().compareToIgnoreCase(o2.getID());
|
||||
}
|
||||
}
|
||||
|
||||
private static class SourceWrapper implements Comparable<SourceWrapper> {
|
||||
private final FileType myFileType;
|
||||
private final PsiViewerExtension myExtension;
|
||||
|
||||
public SourceWrapper(final FileType fileType) {
|
||||
myFileType = fileType;
|
||||
myExtension = null;
|
||||
}
|
||||
|
||||
public SourceWrapper(final PsiViewerExtension extension) {
|
||||
myFileType = null;
|
||||
myExtension = extension;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return myFileType != null ? myFileType.getName() + " file" : myExtension.getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon() {
|
||||
return myFileType != null ? myFileType.getIcon() : myExtension.getIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final SourceWrapper o) {
|
||||
return o == null ? -1 : getText().compareToIgnoreCase(o.getText());
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
public PsiViewerDialog(Project project, boolean modal) {
|
||||
super(project, true);
|
||||
setTitle("PSI Viewer");
|
||||
myProject = project;
|
||||
setTitle("PSI Viewer");
|
||||
setModal(modal);
|
||||
setOKButtonText("&Build PSI Tree");
|
||||
setCancelButtonText("&Close");
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
initBorders();
|
||||
|
||||
myTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode()));
|
||||
UIUtil.setLineStyleAngled(myTree);
|
||||
myTree.setRootVisible(false);
|
||||
@@ -159,24 +190,16 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
final TreeCellRenderer renderer = myTree.getCellRenderer();
|
||||
myTree.setCellRenderer(new TreeCellRenderer() {
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
final Component c = renderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
if (value instanceof DefaultMutableTreeNode) {
|
||||
final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
|
||||
if (userObject instanceof ViewerNodeDescriptor) {
|
||||
final Object element = ((ViewerNodeDescriptor)userObject).getElement();
|
||||
if ((element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null)
|
||||
|| element instanceof ViewerTreeStructure.Inject) {
|
||||
final TextAttributes attr =
|
||||
EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.INJECTED_LANGUAGE_FRAGMENT);
|
||||
c.setBackground(attr.getBackgroundColor());
|
||||
|
||||
if ((element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null) ||
|
||||
element instanceof ViewerTreeStructure.Inject) {
|
||||
final TextAttributes attr = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.INJECTED_LANGUAGE_FRAGMENT);
|
||||
c.setBackground(attr.getBackgroundColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,8 +209,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
ToolTipManager.sharedInstance().registerComponent(myTree);
|
||||
TreeUtil.installActions(myTree);
|
||||
new TreeSpeedSearch(myTree);
|
||||
myTreeBuilder = new ViewerTreeBuilder(project, myTree);
|
||||
|
||||
myTreeBuilder = new ViewerTreeBuilder(myProject, myTree);
|
||||
myTree.addTreeSelectionListener(new MyTreeSelectionListener());
|
||||
|
||||
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree);
|
||||
@@ -216,54 +238,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
});
|
||||
|
||||
setModal(modal);
|
||||
setOKButtonText("&Build PSI Tree");
|
||||
init();
|
||||
}
|
||||
|
||||
//private void initIcons() {
|
||||
// final PsiFileFactory factory = PsiFileFactory.getInstance(myProject);
|
||||
// final FileTypeManager typeManager = FileTypeManager.getInstance();
|
||||
// for (Object obj : handlers.values()) {
|
||||
// if (obj instanceof LanguageFileType) {
|
||||
// LanguageFileType type = (LanguageFileType)obj;
|
||||
// if (!type.isBinary()) {
|
||||
// for (String ext : getAllExtentions(type)) {
|
||||
// final String name = "dummy." + ext;
|
||||
// if (!typeManager.getFileTypeByFileName(name).isBinary()) {
|
||||
// final Icon icon = factory.createFileFromText(name, " ").getIcon(0);
|
||||
//
|
||||
// if (icon != null) {
|
||||
// EXT_ICONS.put(ext, icon);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
protected String getDimensionServiceKey() {
|
||||
return "#com.intellij.internal.psiView.PsiViewerDialog";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHelpId() {
|
||||
return "reference.psi.viewer";
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myEditor.getContentComponent();
|
||||
}
|
||||
|
||||
private void updatePresentation(Presentation p) {
|
||||
myPresentation.setText(p.getText());
|
||||
myPresentation.setIcon(p.getIcon());
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
initBorders();
|
||||
final List<Presentation> items = new ArrayList<Presentation>();
|
||||
final EditorFactory editorFactory = EditorFactory.getInstance();
|
||||
final Document document = editorFactory.createDocument("");
|
||||
myEditor = (EditorEx)editorFactory.createEditor(document, myProject);
|
||||
@@ -272,17 +246,25 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
myEditor.getSelectionModel().addSelectionListener(myEditorListener);
|
||||
myEditor.getCaretModel().addCaretListener(myEditorListener);
|
||||
|
||||
for (PsiViewerExtension extension : Extensions.getExtensions(PsiViewerExtension.EP_NAME)) {
|
||||
final Presentation p = new Presentation(extension.getName());
|
||||
p.setIcon(extension.getIcon());
|
||||
handlers.put(p.getText(), extension);
|
||||
items.add(p);
|
||||
}
|
||||
getPeer().getWindow().setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
|
||||
@Override
|
||||
public Component getInitialComponent(Window window) {
|
||||
return myEditor.getComponent();
|
||||
}
|
||||
});
|
||||
|
||||
Set<FileType> allFileTypes = new HashSet<FileType>();
|
||||
final PsiViewerSettings settings = PsiViewerSettings.getSettings();
|
||||
final String type = settings.type;
|
||||
SourceWrapper lastUsed = null;
|
||||
for (PsiViewerExtension extension : Extensions.getExtensions(PsiViewerExtension.EP_NAME)) {
|
||||
final SourceWrapper wrapper = new SourceWrapper(extension);
|
||||
mySourceWrappers.add(wrapper);
|
||||
if (lastUsed == null && wrapper.getText().equals(type)) lastUsed = wrapper;
|
||||
}
|
||||
final Set<FileType> allFileTypes = Sets.newHashSet();
|
||||
Collections.addAll(allFileTypes, FileTypeManager.getInstance().getRegisteredFileTypes());
|
||||
for (Language language : Language.getRegisteredLanguages()) {
|
||||
FileType fileType = language.getAssociatedFileType();
|
||||
final FileType fileType = language.getAssociatedFileType();
|
||||
if (fileType != null) {
|
||||
allFileTypes.add(fileType);
|
||||
}
|
||||
@@ -298,19 +280,81 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
!(fileType instanceof AbstractFileType) &&
|
||||
!fileType.isBinary() &&
|
||||
!fileType.isReadOnly()) {
|
||||
final Presentation p = new Presentation(fileType.getName() + " file");
|
||||
p.setIcon(fileType.getIcon());
|
||||
handlers.put(p.getText(), fileType);
|
||||
items.add(p);
|
||||
final SourceWrapper wrapper = new SourceWrapper(fileType);
|
||||
mySourceWrappers.add(wrapper);
|
||||
if (lastUsed == null && wrapper.getText().equals(type)) lastUsed = wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
final Presentation[] popupItems = items.toArray(new Presentation[items.size()]);
|
||||
Arrays.sort(popupItems, new Comparator<Presentation>() {
|
||||
public int compare(Presentation p1, Presentation p2) {
|
||||
return p1.getText().toUpperCase().compareTo(p2.getText().toUpperCase());
|
||||
myFileTypeComboBox.setModel(new CollectionComboBoxModel(Lists.newArrayList(mySourceWrappers), lastUsed));
|
||||
myFileTypeComboBox.setRenderer(new ListCellRendererWrapper<SourceWrapper>(myFileTypeComboBox.getRenderer()) {
|
||||
@Override
|
||||
public void customize(JList list, SourceWrapper value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value != null) {
|
||||
setText(value.getText());
|
||||
setIcon(value.getIcon());
|
||||
}
|
||||
}
|
||||
});
|
||||
myFileTypeComboBox.setKeySelectionManager(new JComboBox.KeySelectionManager() {
|
||||
private static final int TIMEOUT = 1000; // ms
|
||||
private final StringBuilder myPrefix = new StringBuilder();
|
||||
private long myTimeStamp = 0;
|
||||
|
||||
@Override
|
||||
public int selectionForKey(char ch, ComboBoxModel model) {
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now - myTimeStamp > TIMEOUT) {
|
||||
myPrefix.delete(0, myPrefix.length());
|
||||
}
|
||||
myTimeStamp = now;
|
||||
|
||||
if (Character.isLetterOrDigit(ch)) {
|
||||
myPrefix.append(ch);
|
||||
}
|
||||
else if (ch == '\b') {
|
||||
myPrefix.delete(0, myPrefix.length());
|
||||
return 0;
|
||||
}
|
||||
|
||||
final String prefix = myPrefix.toString().toLowerCase();
|
||||
for (int i = 0, size = model.getSize(); i < size; i++) {
|
||||
final SourceWrapper item = (SourceWrapper)model.getElementAt(i);
|
||||
if (item.getText().toLowerCase().startsWith(prefix)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
myFileTypeComboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateDialectsCombo(null);
|
||||
updateExtensionsCombo();
|
||||
updateEditor();
|
||||
}
|
||||
});
|
||||
myFileTypeComboBox.addFocusListener(new AutoExpandFocusListener(myFileTypeComboBox));
|
||||
if (lastUsed == null && mySourceWrappers.size() > 0) {
|
||||
myFileTypeComboBox.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
myDialectComboBox.setRenderer(new ListCellRendererWrapper<Language>(myDialectComboBox.getRenderer()) {
|
||||
@Override
|
||||
public void customize(final JList list, final Language value, final int index, final boolean selected, final boolean hasFocus) {
|
||||
setText(value != null ? value.getDisplayName() : "<default>");
|
||||
}
|
||||
});
|
||||
myDialectComboBox.addFocusListener(new AutoExpandFocusListener(myDialectComboBox));
|
||||
|
||||
myExtensionComboBox.setRenderer(new ListCellRendererWrapper<String>(myExtensionComboBox.getRenderer()) {
|
||||
@Override
|
||||
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value != null) setText("." + value);
|
||||
}
|
||||
});
|
||||
myExtensionComboBox.addFocusListener(new AutoExpandFocusListener(myExtensionComboBox));
|
||||
|
||||
final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
|
||||
myShowWhiteSpacesBox.addActionListener(new ActionListener() {
|
||||
@@ -325,73 +369,31 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
myTreeBuilder.queueUpdate();
|
||||
}
|
||||
});
|
||||
myTextPanel.setLayout(new BorderLayout());
|
||||
myTextPanel.add(myEditor.getComponent(), BorderLayout.CENTER);
|
||||
|
||||
myGroup = new DefaultActionGroup();
|
||||
for (final Presentation popupItem : popupItems) {
|
||||
myGroup.add(new PopupItemAction(popupItem));
|
||||
}
|
||||
|
||||
final PsiViewerSettings settings = PsiViewerSettings.getSettings();
|
||||
final String type = settings.type;
|
||||
for (Presentation popupItem : popupItems) {
|
||||
if (popupItem.getText().equals(type)) {
|
||||
updatePresentation(popupItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
myEditor.getDocument().setText(settings.text);
|
||||
myEditor.getSelectionModel().setSelection(0, settings.text.length());
|
||||
}
|
||||
});
|
||||
|
||||
myShowWhiteSpacesBox.setSelected(settings.showWhiteSpaces);
|
||||
treeStructure.setShowWhiteSpaces(settings.showWhiteSpaces);
|
||||
myShowTreeNodesCheckBox.setSelected(settings.showTreeNodes);
|
||||
treeStructure.setShowTreeNodes(settings.showTreeNodes);
|
||||
|
||||
final ChoosePsiTypeButton typeButton = new ChoosePsiTypeButton();
|
||||
myButtonPanel.add(typeButton.createCustomComponent(myPresentation), BorderLayout.CENTER);
|
||||
myTextPanel.setLayout(new BorderLayout());
|
||||
myTextPanel.add(myEditor.getComponent(), BorderLayout.CENTER);
|
||||
|
||||
updateDialectsCombo();
|
||||
updateExtentionsCombo();
|
||||
myDialectsComboBox.setRenderer(new ListCellRendererWrapper<Language>(myDialectsComboBox.getRenderer()) {
|
||||
@Override
|
||||
public void customize(final JList list, final Language value, final int index, final boolean selected, final boolean hasFocus) {
|
||||
setText(value != null ? value.getDisplayName() : "<no dialect>");
|
||||
}
|
||||
});
|
||||
|
||||
//if (EXT_ICONS == null) {
|
||||
// initIcons();
|
||||
//}
|
||||
//myExtensionComboBox.setRenderer(new DefaultListCellRenderer() {
|
||||
// @Override
|
||||
// public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
// if (value instanceof String) {
|
||||
// return new JLabel(((String)value).toLowerCase());
|
||||
// }
|
||||
// return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
// }
|
||||
//});
|
||||
|
||||
if (myDialectsComboBox.isVisible()) {
|
||||
for (int i = 0; i < myLanguageDialects.length; i++) {
|
||||
if (settings.dialect.equals(myLanguageDialects[i].toString())) {
|
||||
myDialectsComboBox.setSelectedIndex(i+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
|
||||
try {
|
||||
myEditor.getDocument().setText(settings.text);
|
||||
myEditor.getSelectionModel().setSelection(0, settings.text.length());
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
updateDialectsCombo(settings.dialect);
|
||||
updateExtensionsCombo();
|
||||
|
||||
registerCustomKeyboardActions();
|
||||
|
||||
final Dimension size = DimensionService.getInstance().getSize(getDimensionServiceKey(), myProject);
|
||||
if (size == null) {
|
||||
DimensionService.getInstance().setSize(getDimensionServiceKey(), new Dimension(600, 600));
|
||||
DimensionService.getInstance().setSize(getDimensionServiceKey(), new Dimension(800, 600));
|
||||
}
|
||||
myTextSplit.setDividerLocation(settings.textDividerLocation);
|
||||
myTreeSplit.setDividerLocation(settings.treeDividerLocation);
|
||||
@@ -400,62 +402,62 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
super.init();
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey() {
|
||||
return "#com.intellij.internal.psiView.PsiViewerDialog";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHelpId() {
|
||||
return "reference.psi.viewer";
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myEditor.getContentComponent();
|
||||
}
|
||||
|
||||
private void registerCustomKeyboardActions() {
|
||||
final Component component = myButtonPanel.getComponents()[0];
|
||||
if (component instanceof JComponent) {
|
||||
final Component button = ((JComponent)component).getComponents()[0];
|
||||
if (button instanceof JButton) {
|
||||
final JButton jButton = (JButton)button;
|
||||
final int mask = SystemInfo.isMac ? KeyEvent.META_DOWN_MASK : KeyEvent.ALT_DOWN_MASK;
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
jButton.doClick();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_P, mask));
|
||||
final int mask = SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.ALT_DOWN_MASK;
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusEditor();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_T, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusTree();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusTree();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
|
||||
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusTree();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusRefs();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_R, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (myRefs.isFocusOwner()) {
|
||||
focusTree();
|
||||
}
|
||||
else if (myTree.isFocusOwner()) {
|
||||
focusRefs();
|
||||
}
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusEditor();
|
||||
}
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_T, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusTree();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusTree();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusTree();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
focusRefs();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_R, mask));
|
||||
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (myRefs.isFocusOwner()) {
|
||||
focusTree();
|
||||
}
|
||||
else if (myTree.isFocusOwner()) {
|
||||
focusRefs();
|
||||
}
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
|
||||
}
|
||||
|
||||
private void registerKeyboardAction(ActionListener actionListener, KeyStroke keyStroke) {
|
||||
@@ -503,33 +505,45 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateDialectsCombo() {
|
||||
final SortedComboBoxModel<Language> model = new SortedComboBoxModel<Language>(DIALECTS_COMPARATOR);
|
||||
final Object handler = getHandler();
|
||||
if (handler instanceof LanguageFileType) {
|
||||
final Language baseLang = ((LanguageFileType)handler).getLanguage();
|
||||
myLanguageDialects = LanguageUtil.getLanguageDialects(baseLang);
|
||||
Arrays.sort(myLanguageDialects, DIALECTS_COMPARATOR);
|
||||
model.setAll(myLanguageDialects);
|
||||
model.add(null);
|
||||
private void updateDialectsCombo(@Nullable final String lastUsed) {
|
||||
final Object source = getSource();
|
||||
if (source instanceof LanguageFileType) {
|
||||
final Language baseLang = ((LanguageFileType)source).getLanguage();
|
||||
final SortedComboBoxModel<Language> model = new SortedComboBoxModel<Language>(new DialectsComparator(baseLang));
|
||||
model.add(baseLang);
|
||||
model.addAll(LanguageUtil.getLanguageDialects(baseLang));
|
||||
myDialectComboBox.setModel(model);
|
||||
}
|
||||
myDialectsComboBox.setModel(model);
|
||||
myDialectsComboBox.setVisible(model.getSize() > 1);
|
||||
if (!myDialectsComboBox.isVisible()) {
|
||||
myLanguageDialects = new Language[0];
|
||||
else {
|
||||
myDialectComboBox.setModel(new DefaultComboBoxModel());
|
||||
}
|
||||
|
||||
final int size = myDialectComboBox.getModel().getSize();
|
||||
final boolean visible = size > 1;
|
||||
myDialectLabel.setVisible(visible);
|
||||
myDialectComboBox.setVisible(visible);
|
||||
|
||||
if (visible && lastUsed != null) {
|
||||
final SortedComboBoxModel model = (SortedComboBoxModel)myDialectComboBox.getModel();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (lastUsed.equals(model.get(i).toString())) {
|
||||
myDialectComboBox.setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
myDialectComboBox.setSelectedIndex(size > 0 ? 0 : -1);
|
||||
}
|
||||
|
||||
private void updateExtentionsCombo() {
|
||||
final Object handler = getHandler();
|
||||
|
||||
if (handler instanceof LanguageFileType) {
|
||||
final List<String> exts = getAllExtentions((LanguageFileType)handler);
|
||||
if (exts.size() > 1) {
|
||||
final ExtensionComparator comp = new ExtensionComparator(exts.get(0));
|
||||
Collections.sort(exts, comp);
|
||||
private void updateExtensionsCombo() {
|
||||
final Object source = getSource();
|
||||
if (source instanceof LanguageFileType) {
|
||||
final List<String> extensions = getAllExtensions((LanguageFileType)source);
|
||||
if (extensions.size() > 1) {
|
||||
final ExtensionComparator comp = new ExtensionComparator(extensions.get(0));
|
||||
Collections.sort(extensions, comp);
|
||||
final SortedComboBoxModel<String> model = new SortedComboBoxModel<String>(comp);
|
||||
model.setAll(exts);
|
||||
model.setAll(extensions);
|
||||
myExtensionComboBox.setModel(model);
|
||||
myExtensionComboBox.setVisible(true);
|
||||
myExtensionLabel.setVisible(true);
|
||||
@@ -542,58 +556,61 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
|
||||
private static final Pattern EXT_PATTERN = Pattern.compile("[a-z0-9]*");
|
||||
private static List<String> getAllExtentions(LanguageFileType fileType) {
|
||||
|
||||
private static List<String> getAllExtensions(LanguageFileType fileType) {
|
||||
final List<FileNameMatcher> associations = FileTypeManager.getInstance().getAssociations(fileType);
|
||||
final List<String> exts = new ArrayList<String>();
|
||||
exts.add(fileType.getDefaultExtension().toLowerCase());
|
||||
final List<String> extensions = new ArrayList<String>();
|
||||
extensions.add(fileType.getDefaultExtension().toLowerCase());
|
||||
for (FileNameMatcher matcher : associations) {
|
||||
final String presentableString = matcher.getPresentableString().toLowerCase();
|
||||
if (presentableString.startsWith("*.")) {
|
||||
final String ext = presentableString.substring(2);
|
||||
if (ext.length() > 0 && !exts.contains(ext) && EXT_PATTERN.matcher(ext).matches()) {
|
||||
exts.add(ext);
|
||||
if (ext.length() > 0 && !extensions.contains(ext) && EXT_PATTERN.matcher(ext).matches()) {
|
||||
extensions.add(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return exts;
|
||||
return extensions;
|
||||
}
|
||||
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
private Object getHandler() {
|
||||
return handlers.get(myPresentation.getText());
|
||||
@Nullable
|
||||
private Object getSource() {
|
||||
final SourceWrapper wrapper = (SourceWrapper)myFileTypeComboBox.getSelectedItem();
|
||||
if (wrapper != null) {
|
||||
return wrapper.myFileType != null ? wrapper.myFileType : wrapper.myExtension;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
final String text = myEditor.getDocument().getText();
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
//if (text.trim().length() == 0) return;
|
||||
|
||||
myLastParsedText = text;
|
||||
myLastParsedTextHashCode = text.hashCode();
|
||||
myNewDocumentHashCode = myLastParsedTextHashCode;
|
||||
PsiElement rootElement = null;
|
||||
final Object handler = getHandler();
|
||||
|
||||
final Object source = getSource();
|
||||
try {
|
||||
if (handler instanceof PsiViewerExtension) {
|
||||
final PsiViewerExtension ext = (PsiViewerExtension)handler;
|
||||
if (source instanceof PsiViewerExtension) {
|
||||
final PsiViewerExtension ext = (PsiViewerExtension)source;
|
||||
rootElement = ext.createElement(myProject, text);
|
||||
}
|
||||
else if (handler instanceof FileType) {
|
||||
final FileType type = (FileType)handler;
|
||||
else if (source instanceof FileType) {
|
||||
final FileType type = (FileType)source;
|
||||
String ext = type.getDefaultExtension();
|
||||
if (myExtensionComboBox.isVisible()) {
|
||||
ext = myExtensionComboBox.getSelectedItem().toString().toLowerCase();
|
||||
}
|
||||
if (type instanceof LanguageFileType) {
|
||||
final Language language = ((LanguageFileType)type).getLanguage();
|
||||
final Language dialect = (Language)myDialectsComboBox.getSelectedItem();
|
||||
rootElement = PsiFileFactory.getInstance(myProject)
|
||||
.createFileFromText("Dummy." + ext, dialect == null ? language : dialect, text);
|
||||
final Language dialect = (Language)myDialectComboBox.getSelectedItem();
|
||||
rootElement = PsiFileFactory.getInstance(myProject).createFileFromText("Dummy." + ext, dialect == null ? language : dialect, text);
|
||||
}
|
||||
else {
|
||||
rootElement = PsiFileFactory.getInstance(myProject).createFileFromText("Dummy." + ext, text);
|
||||
@@ -601,9 +618,9 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
focusTree();
|
||||
}
|
||||
catch (IncorrectOperationException e1) {
|
||||
catch (IncorrectOperationException e) {
|
||||
rootElement = null;
|
||||
Messages.showMessageDialog(myProject, e1.getMessage(), "Error", Messages.getErrorIcon());
|
||||
Messages.showMessageDialog(myProject, e.getMessage(), "Error", Messages.getErrorIcon());
|
||||
}
|
||||
ViewerTreeStructure structure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
|
||||
structure.setRootPsiElement(rootElement);
|
||||
@@ -722,12 +739,13 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
|
||||
public void doCancelAction() {
|
||||
final PsiViewerSettings settings = PsiViewerSettings.getSettings();
|
||||
settings.type = myPresentation.getText();
|
||||
final SourceWrapper wrapper = (SourceWrapper)myFileTypeComboBox.getSelectedItem();
|
||||
if (wrapper != null) settings.type = wrapper.getText();
|
||||
settings.text = myEditor.getDocument().getText();
|
||||
settings.showTreeNodes = myShowTreeNodesCheckBox.isSelected();
|
||||
settings.showWhiteSpaces = myShowWhiteSpacesBox.isSelected();
|
||||
final Object selectedDialect = myDialectsComboBox.getSelectedItem();
|
||||
settings.dialect = myDialectsComboBox.isVisible() && selectedDialect != null ? selectedDialect.toString() : "";
|
||||
final Object selectedDialect = myDialectComboBox.getSelectedItem();
|
||||
settings.dialect = myDialectComboBox.isVisible() && selectedDialect != null ? selectedDialect.toString() : "";
|
||||
settings.textDividerLocation = myTextSplit.getDividerLocation();
|
||||
settings.treeDividerLocation = myTreeSplit.getDividerLocation();
|
||||
super.doCancelAction();
|
||||
@@ -744,22 +762,21 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
private PsiElement resolve(int index) {
|
||||
final PsiElement element = getPsiElement();
|
||||
if (element == null) return null;
|
||||
Object o = myRefs.getClientProperty(REFS_CACHE);
|
||||
if (o == null) {
|
||||
myRefs.putClientProperty(REFS_CACHE, o = new HashMap());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<PsiElement, PsiElement[]> map = (Map<PsiElement, PsiElement[]>)myRefs.getClientProperty(REFS_CACHE);
|
||||
if (map == null) {
|
||||
myRefs.putClientProperty(REFS_CACHE, map = new HashMap<PsiElement, PsiElement[]>());
|
||||
}
|
||||
HashMap map = (HashMap)o;
|
||||
Object cache = map.get(element);
|
||||
PsiElement[] cache = map.get(element);
|
||||
if (cache == null) {
|
||||
final PsiReference[] references = element.getReferences();
|
||||
cache = new PsiElement[references.length];
|
||||
for (int i = 0; i < references.length; i++) {
|
||||
((PsiElement[])cache)[i] = references[i].resolve();
|
||||
cache[i] = references[i].resolve();
|
||||
}
|
||||
map.put(element, cache);
|
||||
}
|
||||
PsiElement[] elements = (PsiElement[])cache;
|
||||
return index >= elements.length ? null : elements[index];
|
||||
return index >= cache.length ? null : cache[index];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -779,7 +796,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static TreeNode findNodeWithObject(final Object object, final TreeModel model, final Object parent) {
|
||||
for (int i = 0; i < model.getChildCount(parent); i++) {
|
||||
@@ -794,25 +810,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private class ChoosePsiTypeButton extends ComboBoxAction {
|
||||
protected int getMaxRows() {
|
||||
return 15;
|
||||
}
|
||||
|
||||
protected int getMinWidth() {
|
||||
return 150;
|
||||
}
|
||||
|
||||
protected int getMinHeight() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
|
||||
return myGroup;
|
||||
}
|
||||
}
|
||||
|
||||
private class GoToListener implements KeyListener, MouseListener, ListSelectionListener {
|
||||
private RangeHighlighter myHighlighter;
|
||||
private final TextAttributes myAttributes =
|
||||
@@ -842,8 +839,8 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
clearSelection();
|
||||
updateDialectsCombo();
|
||||
updateExtentionsCombo();
|
||||
updateDialectsCombo(null);
|
||||
updateExtensionsCombo();
|
||||
final int ind = myRefs.getSelectedIndex();
|
||||
final PsiElement element = getPsiElement();
|
||||
if (ind > -1 && element != null) {
|
||||
@@ -870,7 +867,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
|
||||
public void clearSelection() {
|
||||
if (myHighlighter != null && ArrayUtil.contains(myHighlighter, myEditor.getMarkupModel().getAllHighlighters())) {
|
||||
if (myHighlighter != null && ArrayUtil.contains(myHighlighter, (Object[])myEditor.getMarkupModel().getAllHighlighters())) {
|
||||
myHighlighter.dispose();
|
||||
myHighlighter = null;
|
||||
}
|
||||
@@ -884,27 +881,13 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
}
|
||||
|
||||
private class PopupItemAction extends AnAction implements DumbAware {
|
||||
public PopupItemAction(Presentation p) {
|
||||
super(p.getText(), p.getText(), p.getIcon());
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
updatePresentation(e.getPresentation());
|
||||
updateDialectsCombo();
|
||||
updateExtentionsCombo();
|
||||
updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
private FileType getFileType() {
|
||||
Object handler = getHandler();
|
||||
return handler instanceof FileType ? (FileType)handler :
|
||||
handler instanceof PsiViewerExtension ? ((PsiViewerExtension)handler).getDefaultFileType() : PlainTextFileType.INSTANCE;
|
||||
}
|
||||
|
||||
private void updateEditor() {
|
||||
myEditor.setHighlighter(EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, getFileType()));
|
||||
// todo: consider dialect here
|
||||
final Object source = getSource();
|
||||
final FileType fileType = source instanceof FileType ? (FileType)source :
|
||||
source instanceof PsiViewerExtension ? ((PsiViewerExtension)source).getDefaultFileType() :
|
||||
PlainTextFileType.INSTANCE;
|
||||
myEditor.setHighlighter(EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, fileType));
|
||||
}
|
||||
|
||||
private class EditorListener implements CaretListener, SelectionListener, DocumentListener {
|
||||
@@ -928,6 +911,15 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
myTreeBuilder.select(element);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement findCommonParent(PsiElement start, PsiElement end) {
|
||||
final TextRange range = end.getTextRange();
|
||||
while (start != null && !start.getTextRange().contains(range)) {
|
||||
start = start.getParent();
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
private boolean available() {
|
||||
return myLastParsedTextHashCode == myNewDocumentHashCode && myEditor.getContentComponent().hasFocus();
|
||||
}
|
||||
@@ -945,4 +937,30 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
|
||||
myNewDocumentHashCode = event.getDocument().getText().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static class AutoExpandFocusListener extends FocusAdapter {
|
||||
private final JComboBox myComboBox;
|
||||
private final Component myParent;
|
||||
|
||||
private AutoExpandFocusListener(final JComboBox comboBox) {
|
||||
myComboBox = comboBox;
|
||||
myParent = UIUtil.findUltimateParent(myComboBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained(final FocusEvent e) {
|
||||
final Component from = e.getOppositeComponent();
|
||||
if (!e.isTemporary() && from != null && !myComboBox.isPopupVisible() && isUnder(from, myParent)) {
|
||||
myComboBox.setPopupVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUnder(Component component, final Component parent) {
|
||||
while (component != null) {
|
||||
if (component == parent) return true;
|
||||
component = component.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user