diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.form b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.form
index 53d92b97c195..2b82b4967968 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.form
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.form
@@ -26,9 +26,7 @@
-
-
-
+
@@ -57,9 +55,7 @@
-
-
-
+
@@ -68,9 +64,7 @@
-
-
-
+
@@ -80,20 +74,19 @@
-
+
-
+
-
+
-
@@ -101,45 +94,17 @@
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -148,7 +113,7 @@
-
+
@@ -157,11 +122,49 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
index 09974f4929db..e04e309425f0 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
@@ -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 handlers = new HashMap();
- 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 {
+ private final Set 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 {
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 DIALECTS_COMPARATOR = new Comparator() {
- 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 {
+ 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 {
+ 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 items = new ArrayList();
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 allFileTypes = new HashSet();
+ 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 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() {
- 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(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(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() : "");
+ }
+ });
+ myDialectComboBox.addFocusListener(new AutoExpandFocusListener(myDialectComboBox));
+
+ myExtensionComboBox.setRenderer(new ListCellRendererWrapper(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(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() : "");
- }
- });
-
- //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 model = new SortedComboBoxModel(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 model = new SortedComboBoxModel(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 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 extensions = getAllExtensions((LanguageFileType)source);
+ if (extensions.size() > 1) {
+ final ExtensionComparator comp = new ExtensionComparator(extensions.get(0));
+ Collections.sort(extensions, comp);
final SortedComboBoxModel model = new SortedComboBoxModel(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 getAllExtentions(LanguageFileType fileType) {
+
+ private static List getAllExtensions(LanguageFileType fileType) {
final List associations = FileTypeManager.getInstance().getAssociations(fileType);
- final List exts = new ArrayList();
- exts.add(fileType.getDefaultExtension().toLowerCase());
+ final List extensions = new ArrayList();
+ 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 map = (Map)myRefs.getClientProperty(REFS_CACHE);
+ if (map == null) {
+ myRefs.putClientProperty(REFS_CACHE, map = new HashMap());
}
- 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;
+ }
+ }
}