280e4c7736b16fedcfa53bc485efba6c222bd20f
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / actions / GotoFileAction.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.ide.actions;
18
19 import com.intellij.featureStatistics.FeatureUsageTracker;
20 import com.intellij.ide.util.gotoByName.*;
21 import com.intellij.openapi.actionSystem.AnActionEvent;
22 import com.intellij.openapi.actionSystem.CommonDataKeys;
23 import com.intellij.openapi.application.ApplicationManager;
24 import com.intellij.openapi.application.ModalityState;
25 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
26 import com.intellij.openapi.fileTypes.FileType;
27 import com.intellij.openapi.fileTypes.FileTypeManager;
28 import com.intellij.openapi.fileTypes.FileTypes;
29 import com.intellij.openapi.project.DumbAware;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.vfs.VirtualFile;
32 import com.intellij.pom.Navigatable;
33 import com.intellij.psi.PsiElement;
34 import com.intellij.psi.PsiFile;
35 import com.intellij.util.containers.ContainerUtil;
36 import org.jetbrains.annotations.NotNull;
37
38 import javax.swing.*;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.Comparator;
42 import java.util.List;
43
44 /**
45  * "Go to | File" action implementation.
46  *
47  * @author Eugene Belyaev
48  * @author Constantine.Plotnikov
49  */
50 public class GotoFileAction extends GotoActionBase implements DumbAware {
51   public static final String ID = "GotoFile";
52
53   @Override
54   public void gotoActionPerformed(AnActionEvent e) {
55     FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file");
56     final Project project = e.getData(CommonDataKeys.PROJECT);
57     final GotoFileModel gotoFileModel = new GotoFileModel(project);
58     GotoActionCallback<FileType> callback = new GotoActionCallback<FileType>() {
59       @Override
60       protected ChooseByNameFilter<FileType> createFilter(@NotNull ChooseByNamePopup popup) {
61         return new GotoFileFilter(popup, gotoFileModel, project);
62       }
63
64       @Override
65       public void elementChosen(final ChooseByNamePopup popup, final Object element) {
66         if (element == null) return;
67         ApplicationManager.getApplication().invokeLater(new Runnable() {
68           @Override
69           public void run() {
70             Navigatable n = (Navigatable)element;
71
72             //this is for better cursor position
73             if (element instanceof PsiFile) {
74               VirtualFile vfile = ((PsiFile)element).getVirtualFile();
75               if (vfile == null) return;
76               n = new OpenFileDescriptor(project, vfile, popup.getLinePosition(), popup.getColumnPosition()).setUseCurrentWindow(popup.isOpenInCurrentWindowRequested());
77             }
78
79             if (!n.canNavigate()) return;
80             n.navigate(true);
81           }
82         }, ModalityState.NON_MODAL);
83       }
84     };
85     PsiElement context = getPsiContext(e);
86     showNavigationPopup(e, gotoFileModel, callback, "Files matching pattern", true, true, new GotoFileItemProvider(project, context));
87   }
88
89   protected static class GotoFileFilter extends ChooseByNameFilter<FileType> {
90     GotoFileFilter(final ChooseByNamePopup popup, GotoFileModel model, final Project project) {
91       super(popup, model, GotoFileConfiguration.getInstance(project), project);
92     }
93
94     @Override
95     @NotNull
96     protected List<FileType> getAllFilterValues() {
97       List<FileType> elements = new ArrayList<FileType>();
98       ContainerUtil.addAll(elements, FileTypeManager.getInstance().getRegisteredFileTypes());
99       Collections.sort(elements, FileTypeComparator.INSTANCE);
100       return elements;
101     }
102
103     @Override
104     protected String textForFilterValue(@NotNull FileType value) {
105       return value.getName();
106     }
107
108     @Override
109     protected Icon iconForFilterValue(@NotNull FileType value) {
110       return value.getIcon();
111     }
112   }
113
114   /**
115    * A file type comparator. The comparison rules are applied in the following order.
116    * <ol>
117    * <li>Unknown file type is greatest.</li>
118    * <li>Text files are less then binary ones.</li>
119    * <li>File type with greater name is greater (case is ignored).</li>
120    * </ol>
121    */
122   static class FileTypeComparator implements Comparator<FileType> {
123     /**
124      * an instance of comparator
125      */
126     static final Comparator<FileType> INSTANCE = new FileTypeComparator();
127
128     /**
129      * {@inheritDoc}
130      */
131     @Override
132     public int compare(final FileType o1, final FileType o2) {
133       if (o1 == o2) {
134         return 0;
135       }
136       if (o1 == FileTypes.UNKNOWN) {
137         return 1;
138       }
139       if (o2 == FileTypes.UNKNOWN) {
140         return -1;
141       }
142       if (o1.isBinary() && !o2.isBinary()) {
143         return 1;
144       }
145       if (!o1.isBinary() && o2.isBinary()) {
146         return -1;
147       }
148       return o1.getName().compareToIgnoreCase(o2.getName());
149     }
150   }
151
152 }