selectAll on dialog open
[fedora-idea.git] / platform / lang-impl / src / com / intellij / internal / psiView / PsiViewerDialog.java
blob5ed15808a2b9c9731c43289d75a3a1701aac42ff
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.internal.psiView;
18 import com.intellij.lang.ASTNode;
19 import com.intellij.lang.Language;
20 import com.intellij.lang.LanguageUtil;
21 import com.intellij.openapi.actionSystem.AnAction;
22 import com.intellij.openapi.actionSystem.AnActionEvent;
23 import com.intellij.openapi.actionSystem.DefaultActionGroup;
24 import com.intellij.openapi.actionSystem.Presentation;
25 import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
26 import com.intellij.openapi.application.ApplicationManager;
27 import com.intellij.openapi.editor.*;
28 import com.intellij.openapi.editor.event.*;
29 import com.intellij.openapi.editor.markup.*;
30 import com.intellij.openapi.extensions.Extensions;
31 import com.intellij.openapi.fileTypes.*;
32 import com.intellij.openapi.fileTypes.impl.AbstractFileType;
33 import com.intellij.openapi.project.DumbAware;
34 import com.intellij.openapi.project.Project;
35 import com.intellij.openapi.ui.DialogWrapper;
36 import com.intellij.openapi.ui.Messages;
37 import com.intellij.openapi.util.DimensionService;
38 import com.intellij.openapi.util.Disposer;
39 import com.intellij.openapi.util.SystemInfo;
40 import com.intellij.openapi.util.TextRange;
41 import com.intellij.openapi.wm.IdeFocusManager;
42 import com.intellij.psi.PsiElement;
43 import com.intellij.psi.PsiFile;
44 import com.intellij.psi.PsiFileFactory;
45 import com.intellij.psi.PsiReference;
46 import com.intellij.psi.search.FilenameIndex;
47 import com.intellij.psi.search.GlobalSearchScope;
48 import com.intellij.psi.util.PsiUtilBase;
49 import com.intellij.ui.SortedComboBoxModel;
50 import com.intellij.ui.TitledBorderWithMnemonic;
51 import com.intellij.ui.TreeSpeedSearch;
52 import com.intellij.ui.treeStructure.Tree;
53 import com.intellij.util.IncorrectOperationException;
54 import com.intellij.util.ui.UIUtil;
55 import com.intellij.util.ui.tree.TreeUtil;
56 import org.jetbrains.annotations.NotNull;
57 import org.jetbrains.annotations.Nullable;
59 import javax.swing.*;
60 import javax.swing.event.ListSelectionEvent;
61 import javax.swing.event.ListSelectionListener;
62 import javax.swing.event.TreeSelectionEvent;
63 import javax.swing.event.TreeSelectionListener;
64 import javax.swing.tree.*;
65 import java.awt.*;
66 import java.awt.event.*;
67 import java.util.*;
68 import java.util.List;
70 /**
71 * @author Konstantin Bulenkov
73 public class PsiViewerDialog extends DialogWrapper {
74 private final Project myProject;
76 private final Tree myTree;
77 private final ViewerTreeBuilder myTreeBuilder;
79 private final JList myRefs;
80 private static String REFS_CACHE = "References Resolve Cache";
82 private Editor myEditor;
83 private String myLastParsedText = null;
85 private JCheckBox myShowWhiteSpacesBox;
86 private JPanel myStructureTreePanel;
87 private JPanel myTextPanel;
88 private JPanel myPanel;
89 private JCheckBox myShowTreeNodesCheckBox;
90 private JComboBox myDialectsComboBox;
91 private JPanel myReferencesPanel;
92 private JPanel myButtonPanel;
93 private JSplitPane myTextSplit;
94 private JSplitPane myTreeSplit;
95 private Presentation myPresentation = new Presentation();
96 private Map<String, Object> handlers = new HashMap<String, Object>();
97 private DefaultActionGroup myGroup;
98 private Language[] myLanguageDialects;
99 private final Color SELECTION_BG_COLOR = new Color(0, 51, 51);
100 private static final Comparator<Language> DIALECTS_COMPARATOR = new Comparator<Language>() {
101 public int compare(final Language o1, final Language o2) {
102 if (o1 == null) return o2 == null ? 0 : -1;
103 if (o2 == null) return 1;
104 return o1.getID().compareTo(o2.getID());
107 private EditorListener myEditorListener = new EditorListener();
108 private int myLastParsedTextHashCode = 17;
109 private int myNewDocumentHashCode = 11;
111 @Nullable
112 private static PsiElement findCommonParent(PsiElement start, PsiElement end) {
113 final TextRange range = end.getTextRange();
114 while (start != null && !start.getTextRange().contains(range)) {
115 start = start.getParent();
117 return start;
120 public PsiViewerDialog(Project project, boolean modal) {
121 super(project, true);
122 setTitle("PSI Viewer");
123 myProject = project;
124 myTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode()));
125 UIUtil.setLineStyleAngled(myTree);
126 myTree.setRootVisible(false);
127 myTree.setShowsRootHandles(true);
128 myTree.updateUI();
129 ToolTipManager.sharedInstance().registerComponent(myTree);
130 TreeUtil.installActions(myTree);
131 new TreeSpeedSearch(myTree);
132 myTreeBuilder = new ViewerTreeBuilder(project, myTree);
134 myTree.addTreeSelectionListener(new MyTreeSelectionListener());
136 JScrollPane scrollPane = new JScrollPane(myTree);
137 JPanel panel = new JPanel(new BorderLayout());
138 panel.add(scrollPane, BorderLayout.CENTER);
139 myStructureTreePanel.setLayout(new BorderLayout());
140 myStructureTreePanel.add(panel, BorderLayout.CENTER);
142 myRefs = new JList(new DefaultListModel());
143 JScrollPane refScrollPane = new JScrollPane(myRefs);
144 JPanel refPanel = new JPanel(new BorderLayout());
145 refPanel.add(refScrollPane, BorderLayout.CENTER);
146 myReferencesPanel.setLayout(new BorderLayout());
147 myReferencesPanel.add(refPanel, BorderLayout.CENTER);
148 final GoToListener listener = new GoToListener();
149 myRefs.addKeyListener(listener);
150 myRefs.addMouseListener(listener);
151 myRefs.getSelectionModel().addListSelectionListener(listener);
152 myRefs.setCellRenderer(new DefaultListCellRenderer() {
153 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
154 final Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
155 if (resolve(index) == null) {
156 comp.setForeground(Color.red);
158 return comp;
162 setModal(modal);
163 setOKButtonText("&Build PSI Tree");
164 init();
167 protected String getDimensionServiceKey() {
168 return "#com.intellij.internal.psiView.PsiViewerDialog";
171 public JComponent getPreferredFocusedComponent() {
172 return myEditor.getContentComponent();
175 private void updatePresentation(Presentation p) {
176 myPresentation.setText(p.getText());
177 myPresentation.setIcon(p.getIcon());
180 protected void init() {
181 initBorders();
182 final List<Presentation> items = new ArrayList<Presentation>();
183 final EditorFactory editorFactory = EditorFactory.getInstance();
184 final Document document = editorFactory.createDocument("");
185 myEditor = editorFactory.createEditor(document, myProject);
186 myEditor.getSettings().setFoldingOutlineShown(false);
187 document.addDocumentListener(myEditorListener);
188 myEditor.getSelectionModel().addSelectionListener(myEditorListener);
189 myEditor.getCaretModel().addCaretListener(myEditorListener);
191 for (PsiViewerExtension extension : Extensions.getExtensions(PsiViewerExtension.EP_NAME)) {
192 final Presentation p = new Presentation(extension.getName());
193 p.setIcon(extension.getIcon());
194 handlers.put(p.getText(), extension);
195 items.add(p);
198 for (FileType fileType : FileTypeManager.getInstance().getRegisteredFileTypes()) {
199 if (fileType != StdFileTypes.GUI_DESIGNER_FORM &&
200 fileType != StdFileTypes.IDEA_MODULE &&
201 fileType != StdFileTypes.IDEA_PROJECT &&
202 fileType != StdFileTypes.IDEA_WORKSPACE &&
203 fileType != FileTypes.ARCHIVE &&
204 fileType != FileTypes.UNKNOWN &&
205 fileType != FileTypes.PLAIN_TEXT &&
206 !(fileType instanceof AbstractFileType) &&
207 !fileType.isBinary() &&
208 !fileType.isReadOnly()) {
209 final Presentation p = new Presentation(fileType.getName() + " file");
210 p.setIcon(fileType.getIcon());
211 handlers.put(p.getText(), fileType);
212 items.add(p);
216 final Presentation[] popupItems = items.toArray(new Presentation[items.size()]);
217 Arrays.sort(popupItems, new Comparator<Presentation>() {
218 public int compare(Presentation p1, Presentation p2) {
219 return p1.getText().toUpperCase().compareTo(p2.getText().toUpperCase());
223 final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
224 myShowWhiteSpacesBox.addActionListener(new ActionListener() {
225 public void actionPerformed(ActionEvent e) {
226 treeStructure.setShowWhiteSpaces(myShowWhiteSpacesBox.isSelected());
227 myTreeBuilder.queueUpdate();
230 myShowTreeNodesCheckBox.addActionListener(new ActionListener() {
231 public void actionPerformed(ActionEvent e) {
232 treeStructure.setShowTreeNodes(myShowTreeNodesCheckBox.isSelected());
233 myTreeBuilder.queueUpdate();
236 myTextPanel.setLayout(new BorderLayout());
237 myTextPanel.add(myEditor.getComponent(), BorderLayout.CENTER);
239 myGroup = new DefaultActionGroup();
240 for (final Presentation popupItem : popupItems) {
241 myGroup.add(new PopupItemAction(popupItem));
244 final PsiViewerSettings settings = PsiViewerSettings.getSettings();
245 final String type = settings.type;
246 for (Presentation popupItem : popupItems) {
247 if (popupItem.getText().equals(type)) {
248 updatePresentation(popupItem);
249 break;
253 ApplicationManager.getApplication().runWriteAction(new Runnable() {
254 public void run() {
255 myEditor.getDocument().setText(settings.text);
256 myEditor.getSelectionModel().setSelection(0, settings.text.length());
260 myShowWhiteSpacesBox.setSelected(settings.showWhiteSpaces);
261 myShowTreeNodesCheckBox.setSelected(settings.showTreeNodes);
263 final ChoosePsiTypeButton typeButton = new ChoosePsiTypeButton();
264 myButtonPanel.add(typeButton.createCustomComponent(myPresentation), BorderLayout.CENTER);
266 updateDialectsCombo();
267 myDialectsComboBox.setRenderer(new DefaultListCellRenderer() {
268 @Override
269 public Component getListCellRendererComponent(JList list, Object value, int index,
270 boolean isSelected, boolean cellHasFocus) {
271 final Component result = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
272 if (value == null) setText("<no dialect>");
273 return result;
277 if (myDialectsComboBox.isVisible()) {
278 for (int i = 0; i < myLanguageDialects.length; i++) {
279 if (settings.dialect.equals(myLanguageDialects[i].toString())) {
280 myDialectsComboBox.setSelectedIndex(i+1);
281 break;
286 registerCustomKeyboardActions();
287 final Dimension size = DimensionService.getInstance().getSize(getDimensionServiceKey(), myProject);
288 if (size == null) {
289 DimensionService.getInstance().setSize(getDimensionServiceKey(), new Dimension(600, 600));
291 myTextSplit.setDividerLocation(settings.textDividerLocation);
292 myTreeSplit.setDividerLocation(settings.treeDividerLocation);
293 super.init();
296 private void registerCustomKeyboardActions() {
297 final Component component = myButtonPanel.getComponents()[0];
298 if (component instanceof JComponent) {
299 final Component button = ((JComponent)component).getComponents()[0];
300 if (button instanceof JButton) {
301 final JButton jButton = (JButton)button;
302 final int mask = SystemInfo.isMac ? KeyEvent.META_DOWN_MASK : KeyEvent.ALT_DOWN_MASK;
303 registerKeyboardAction(new ActionListener() {
304 public void actionPerformed(ActionEvent e) {
305 jButton.doClick();
307 }, KeyStroke.getKeyStroke(KeyEvent.VK_P, mask));
309 registerKeyboardAction(new ActionListener() {
310 public void actionPerformed(ActionEvent e) {
311 focusEditor();
313 }, KeyStroke.getKeyStroke(KeyEvent.VK_T, mask));
315 registerKeyboardAction(new ActionListener() {
316 public void actionPerformed(ActionEvent e) {
317 focusTree();
319 }, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
321 registerKeyboardAction(new ActionListener() {
322 public void actionPerformed(ActionEvent e) {
323 focusTree();
325 }, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
328 registerKeyboardAction(new ActionListener() {
329 public void actionPerformed(ActionEvent e) {
330 focusTree();
332 }, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
334 registerKeyboardAction(new ActionListener() {
335 public void actionPerformed(ActionEvent e) {
336 focusRefs();
338 }, KeyStroke.getKeyStroke(KeyEvent.VK_R, mask));
340 registerKeyboardAction(new ActionListener() {
341 public void actionPerformed(ActionEvent e) {
342 if (myRefs.isFocusOwner()) {
343 focusTree();
345 else if (myTree.isFocusOwner()) {
346 focusRefs();
349 }, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
354 private void registerKeyboardAction(ActionListener actionListener, KeyStroke keyStroke) {
355 getRootPane().registerKeyboardAction(actionListener, keyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
358 private void focusEditor() {
359 IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), true);
362 private void focusTree() {
363 IdeFocusManager.getInstance(myProject).requestFocus(myTree, true);
366 private void focusRefs() {
367 IdeFocusManager.getInstance(myProject).requestFocus(myRefs, true);
368 if (myRefs.getModel().getSize() > 0) {
369 if (myRefs.getSelectedIndex() == -1) {
370 myRefs.setSelectedIndex(0);
375 private void initBorders() {
376 myTextPanel.setBorder(new TitledBorderWithMnemonic("&Text"));
377 myStructureTreePanel.setBorder(new TitledBorderWithMnemonic("PSI &Structure"));
378 myReferencesPanel.setBorder(new TitledBorderWithMnemonic("&References"));
381 @Nullable
382 private PsiElement getPsiElement() {
383 final TreePath path = myTree.getSelectionPath();
384 return path == null ? null : getPsiElement((DefaultMutableTreeNode)path.getLastPathComponent());
387 @Nullable
388 private PsiElement getPsiElement(DefaultMutableTreeNode node) {
389 if (node.getUserObject() instanceof ViewerNodeDescriptor) {
390 ViewerNodeDescriptor descriptor = (ViewerNodeDescriptor)node.getUserObject();
391 Object elementObject = descriptor.getElement();
392 return elementObject instanceof PsiElement
393 ? (PsiElement)elementObject
394 : elementObject instanceof ASTNode ? ((ASTNode)elementObject).getPsi() : null;
396 return null;
399 private void updateDialectsCombo() {
400 final SortedComboBoxModel<Language> model = new SortedComboBoxModel<Language>(DIALECTS_COMPARATOR);
401 final Object handler = getHandler();
402 if (handler instanceof LanguageFileType) {
403 final Language baseLang = ((LanguageFileType)handler).getLanguage();
404 myLanguageDialects = LanguageUtil.getLanguageDialects(baseLang);
405 Arrays.sort(myLanguageDialects, DIALECTS_COMPARATOR);
406 model.setAll(myLanguageDialects);
407 model.add(null);
409 myDialectsComboBox.setModel(model);
410 myDialectsComboBox.setVisible(model.getSize() > 1);
411 if (!myDialectsComboBox.isVisible()) {
412 myLanguageDialects = new Language[0];
416 protected JComponent createCenterPanel() {
417 return myPanel;
420 private Object getHandler() {
421 return handlers.get(myPresentation.getText());
424 protected void doOKAction() {
425 final String text = myEditor.getDocument().getText();
426 if (text.trim().length() == 0) return;
428 myLastParsedText = text;
429 myLastParsedTextHashCode = text.hashCode();
430 myNewDocumentHashCode = myLastParsedTextHashCode;
431 PsiElement rootElement = null;
432 final Object handler = getHandler();
434 try {
435 if (handler instanceof PsiViewerExtension) {
436 final PsiViewerExtension ext = (PsiViewerExtension)handler;
437 rootElement = ext.createElement(myProject, text);
439 else if (handler instanceof FileType) {
440 final FileType type = (FileType)handler;
441 if (type instanceof LanguageFileType) {
442 final Language language = ((LanguageFileType)type).getLanguage();
443 final Language dialect = (Language)myDialectsComboBox.getSelectedItem();
444 rootElement = PsiFileFactory.getInstance(myProject)
445 .createFileFromText("Dummy." + type.getDefaultExtension(), dialect == null ? language : dialect, text);
447 else {
448 rootElement = PsiFileFactory.getInstance(myProject).createFileFromText("Dummy." + type.getDefaultExtension(), text);
451 focusTree();
453 catch (IncorrectOperationException e1) {
454 rootElement = null;
455 Messages.showMessageDialog(myProject, e1.getMessage(), "Error", Messages.getErrorIcon());
457 ViewerTreeStructure structure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
458 structure.setRootPsiElement(rootElement);
460 myTreeBuilder.queueUpdate();
461 myTree.setRootVisible(true);
462 myTree.expandRow(0);
463 myTree.setRootVisible(false);
466 private class MyTreeSelectionListener implements TreeSelectionListener {
467 private final TextAttributes myAttributes;
469 public MyTreeSelectionListener() {
470 myAttributes = new TextAttributes();
471 myAttributes.setBackgroundColor(SELECTION_BG_COLOR);
472 myAttributes.setForegroundColor(Color.white);
475 public void valueChanged(TreeSelectionEvent e) {
476 if (!myEditor.getDocument().getText().equals(myLastParsedText)) return;
477 TreePath path = myTree.getSelectionPath();
478 if (path == null) {
479 clearSelection();
481 else {
482 clearSelection();
483 DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
484 if (!(node.getUserObject() instanceof ViewerNodeDescriptor)) return;
485 ViewerNodeDescriptor descriptor = (ViewerNodeDescriptor)node.getUserObject();
486 Object elementObject = descriptor.getElement();
487 final PsiElement element = elementObject instanceof PsiElement
488 ? (PsiElement)elementObject
489 : elementObject instanceof ASTNode ? ((ASTNode)elementObject).getPsi() : null;
490 if (element != null) {
491 TextRange range = element.getTextRange();
492 int start = range.getStartOffset();
493 int end = range.getEndOffset();
494 final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
495 PsiElement rootPsiElement = treeStructure.getRootPsiElement();
496 if (rootPsiElement != null) {
497 int baseOffset = rootPsiElement.getTextRange().getStartOffset();
498 start -= baseOffset;
499 end -= baseOffset;
502 final int textLength = myEditor.getDocument().getTextLength();
503 if (end <= textLength) {
504 myEditor.getMarkupModel()
505 .addRangeHighlighter(start, end, HighlighterLayer.FIRST + 1, myAttributes, HighlighterTargetArea.EXACT_RANGE);
506 if (myTree.hasFocus()) {
507 myEditor.getCaretModel().moveToOffset(start);
508 myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
509 } else {
510 myEditor.getScrollingModel().scrollTo(myEditor.offsetToLogicalPosition(start), ScrollType.MAKE_VISIBLE);
513 updateReferences(element);
518 public void updateReferences(PsiElement element) {
519 final DefaultListModel model = (DefaultListModel)myRefs.getModel();
520 model.clear();
521 final Object cache = myRefs.getClientProperty(REFS_CACHE);
522 if (cache instanceof Map) {
523 ((Map)cache).clear();
524 } else {
525 myRefs.putClientProperty(REFS_CACHE, new HashMap());
527 if (element != null) {
528 for (PsiReference reference : element.getReferences()) {
529 model.addElement(reference.getClass().getName());
534 private void clearSelection() {
535 myEditor.getMarkupModel().removeAllHighlighters();
539 public void doCancelAction() {
540 final PsiViewerSettings settings = PsiViewerSettings.getSettings();
541 settings.type = myPresentation.getText();
542 settings.text = myEditor.getDocument().getText();
543 settings.showTreeNodes = myShowTreeNodesCheckBox.isSelected();
544 settings.showWhiteSpaces = myShowWhiteSpacesBox.isSelected();
545 final Object selectedDialect = myDialectsComboBox.getSelectedItem();
546 settings.dialect = myDialectsComboBox.isVisible() && selectedDialect != null ? selectedDialect.toString() : "";
547 settings.textDividerLocation = myTextSplit.getDividerLocation();
548 settings.treeDividerLocation = myTreeSplit.getDividerLocation();
549 super.doCancelAction();
552 public void dispose() {
553 Disposer.dispose(myTreeBuilder);
554 EditorFactory.getInstance().releaseEditor(myEditor);
556 super.dispose();
559 @Nullable
560 private PsiElement resolve(int index) {
561 final PsiElement element = getPsiElement();
562 if (element == null) return null;
563 Object o = myRefs.getClientProperty(REFS_CACHE);
564 if (o == null) {
565 myRefs.putClientProperty(REFS_CACHE, o = new HashMap());
567 HashMap map = (HashMap)o;
568 Object cache = map.get(element);
569 if (cache == null) {
570 final PsiReference[] references = element.getReferences();
571 cache = new PsiElement[references.length];
572 for (int i = 0; i < references.length; i++) {
573 ((PsiElement[])cache)[i] = references[i].resolve();
575 map.put(element, cache);
577 PsiElement[] elements = (PsiElement[])cache;
578 return index >= elements.length ? null : elements[index];
581 @Nullable
582 public static TreeNode findNodeWithObject(final Object object, final TreeModel model, final Object parent) {
583 for (int i = 0; i < model.getChildCount(parent); i++) {
584 final DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) model.getChild(parent, i);
585 if (childNode.getUserObject().equals(object)) {
586 return childNode;
587 } else {
588 final TreeNode node = findNodeWithObject(object, model, childNode);
589 if (node != null) return node;
592 return null;
595 private class ChoosePsiTypeButton extends ComboBoxAction {
596 protected int getMaxRows() {
597 return 15;
600 protected int getMinWidth() {
601 return 150;
604 protected int getMinHeight() {
605 return 200;
608 @NotNull
609 protected DefaultActionGroup createPopupActionGroup(JComponent button) {
610 return myGroup;
614 private class GoToListener implements KeyListener, MouseListener, ListSelectionListener {
615 private RangeHighlighter myHighlighter;
616 private final TextAttributes myAttributes =
617 new TextAttributes(Color.white, SELECTION_BG_COLOR, Color.red, EffectType.BOXED, Font.PLAIN);
619 private void navigate() {
620 clearSelection();
621 final Object value = myRefs.getSelectedValue();
622 if (value instanceof String) {
623 final String fqn = (String)value;
624 String filename = fqn;
625 if (fqn.contains(".")) {
626 filename = fqn.substring(fqn.lastIndexOf('.') + 1);
628 if (filename.contains("$")) {
629 filename = filename.substring(0, filename.indexOf('$'));
631 filename += ".java";
632 final PsiFile[] files = FilenameIndex.getFilesByName(myProject, filename, GlobalSearchScope.allScope(myProject));
633 if (files != null && files.length > 0) {
634 files[0].navigate(true);
639 public void keyPressed(KeyEvent e) {
640 if (e.getKeyCode() == KeyEvent.VK_ENTER) {
641 navigate();
645 public void mouseClicked(MouseEvent e) {
646 if (e.getClickCount() > 1) {
647 navigate();
651 public void valueChanged(ListSelectionEvent e) {
652 clearSelection();
653 updateDialectsCombo();
654 final int ind = myRefs.getSelectedIndex();
655 final PsiElement element = getPsiElement();
656 if (ind > -1 && element != null) {
657 final PsiReference[] references = element.getReferences();
658 if (ind < references.length) {
659 final TextRange textRange = references[ind].getRangeInElement();
660 TextRange range = element.getTextRange();
661 int start = range.getStartOffset();
662 int end = range.getEndOffset();
663 final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
664 PsiElement rootPsiElement = treeStructure.getRootPsiElement();
665 if (rootPsiElement != null) {
666 int baseOffset = rootPsiElement.getTextRange().getStartOffset();
667 start -= baseOffset;
668 end -= baseOffset;
671 start += textRange.getStartOffset();
672 end = start + textRange.getLength();
673 myHighlighter = myEditor.getMarkupModel()
674 .addRangeHighlighter(start, end, HighlighterLayer.FIRST + 1, myAttributes, HighlighterTargetArea.EXACT_RANGE);
679 public void clearSelection() {
680 if (myHighlighter != null && Arrays.asList(myEditor.getMarkupModel().getAllHighlighters()).contains(myHighlighter)) {
681 myEditor.getMarkupModel().removeHighlighter(myHighlighter);
682 myHighlighter = null;
686 public void keyTyped(KeyEvent e) {}
687 public void keyReleased(KeyEvent e) {}
688 public void mousePressed(MouseEvent e) {}
689 public void mouseReleased(MouseEvent e) {}
690 public void mouseEntered(MouseEvent e) {}
691 public void mouseExited(MouseEvent e) {}
694 private class PopupItemAction extends AnAction implements DumbAware {
695 public PopupItemAction(Presentation p) {
696 super(p.getText(), p.getText(), p.getIcon());
699 public void actionPerformed(AnActionEvent e) {
700 updatePresentation(e.getPresentation());
701 updateDialectsCombo();
705 private class EditorListener implements CaretListener, SelectionListener, DocumentListener {
706 public void caretPositionChanged(CaretEvent e) {
707 if (!available() || myEditor.getSelectionModel().hasSelection()) return;
708 final PsiFile psiFile = getPsiFile();
709 if (psiFile == null) return;
710 final int offset = myEditor.getCaretModel().getOffset();
711 final PsiElement element = PsiUtilBase.getElementAtOffset(psiFile, offset);
712 myTreeBuilder.select(element);
715 public void selectionChanged(SelectionEvent e) {
716 if (!available() || !myEditor.getSelectionModel().hasSelection()) return;
717 final PsiFile psiFile = getPsiFile();
718 if (psiFile == null) return;
719 final SelectionModel selection = myEditor.getSelectionModel();
720 final int start = selection.getSelectionStart();
721 final int end = selection.getSelectionEnd();
722 final PsiElement element = findCommonParent(PsiUtilBase.getElementAtOffset(psiFile, start), PsiUtilBase.getElementAtOffset(psiFile, end));
723 myTreeBuilder.select(element);
726 private boolean available() {
727 return myLastParsedTextHashCode == myNewDocumentHashCode && myEditor.getContentComponent().hasFocus();
730 @Nullable
731 private PsiFile getPsiFile() {
732 final PsiElement root = ((ViewerTreeStructure)myTreeBuilder.getTreeStructure()).getRootPsiElement();
733 return root instanceof PsiFile ? (PsiFile)root : null;
736 public void beforeDocumentChange(DocumentEvent event) {
739 public void documentChanged(DocumentEvent event) {
740 myNewDocumentHashCode = event.getDocument().getText().hashCode();