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