/*
 * Copyright 2000-2015 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.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.ide.actions;

import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.gotoByName.ChooseByNameFilter;
import com.intellij.ide.util.gotoByName.ChooseByNamePopup;
import com.intellij.ide.util.gotoByName.GotoFileConfiguration;
import com.intellij.ide.util.gotoByName.GotoFileModel;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * "Go to | File" action implementation.
 *
 * @author Eugene Belyaev
 * @author Constantine.Plotnikov
 */
public class GotoFileAction extends GotoActionBase implements DumbAware {
  public static final String ID = "GotoFile";

  @Override
  public void gotoActionPerformed(AnActionEvent e) {
    final Project project = e.getData(CommonDataKeys.PROJECT);
    if (project == null) return;

    FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file");

    final GotoFileModel gotoFileModel = new GotoFileModel(project);
    GotoActionCallback<FileType> callback = new GotoActionCallback<FileType>() {
      @Override
      protected ChooseByNameFilter<FileType> createFilter(@NotNull ChooseByNamePopup popup) {
        return new GotoFileFilter(popup, gotoFileModel, project);
      }

      @Override
      public void elementChosen(final ChooseByNamePopup popup, final Object element) {
        if (element == null) return;
        ApplicationManager.getApplication().invokeLater(new Runnable() {
          @Override
          public void run() {
            Navigatable n = (Navigatable)element;

            //this is for better cursor position
            if (element instanceof PsiFile) {
              VirtualFile file = ((PsiFile)element).getVirtualFile();
              if (file == null) return;
              OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file, popup.getLinePosition(), popup.getColumnPosition());
              n = descriptor.setUseCurrentWindow(popup.isOpenInCurrentWindowRequested());
            }

            if (!n.canNavigate()) return;
            n.navigate(true);
          }
        }, ModalityState.NON_MODAL);
      }
    };
    GotoFileItemProvider provider = new GotoFileItemProvider(project, getPsiContext(e), gotoFileModel);
    showNavigationPopup(e, gotoFileModel, callback, IdeBundle.message("go.to.file.toolwindow.title"), true, true, provider);
  }

  protected static class GotoFileFilter extends ChooseByNameFilter<FileType> {
    GotoFileFilter(final ChooseByNamePopup popup, GotoFileModel model, final Project project) {
      super(popup, model, GotoFileConfiguration.getInstance(project), project);
    }

    @Override
    @NotNull
    protected List<FileType> getAllFilterValues() {
      List<FileType> elements = new ArrayList<FileType>();
      ContainerUtil.addAll(elements, FileTypeManager.getInstance().getRegisteredFileTypes());
      Collections.sort(elements, FileTypeComparator.INSTANCE);
      return elements;
    }

    @Override
    protected String textForFilterValue(@NotNull FileType value) {
      return value.getName();
    }

    @Override
    protected Icon iconForFilterValue(@NotNull FileType value) {
      return value.getIcon();
    }
  }

  /**
   * A file type comparator. The comparison rules are applied in the following order.
   * <ol>
   * <li>Unknown file type is greatest.</li>
   * <li>Text files are less then binary ones.</li>
   * <li>File type with greater name is greater (case is ignored).</li>
   * </ol>
   */
  static class FileTypeComparator implements Comparator<FileType> {
    /**
     * an instance of comparator
     */
    static final Comparator<FileType> INSTANCE = new FileTypeComparator();

    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(final FileType o1, final FileType o2) {
      if (o1 == o2) {
        return 0;
      }
      if (o1 == FileTypes.UNKNOWN) {
        return 1;
      }
      if (o2 == FileTypes.UNKNOWN) {
        return -1;
      }
      if (o1.isBinary() && !o2.isBinary()) {
        return 1;
      }
      if (!o1.isBinary() && o2.isBinary()) {
        return -1;
      }
      return o1.getName().compareToIgnoreCase(o2.getName());
    }
  }
}

@@ -21,9 +21,9 @@
 -201
-5
+6
  Jet
@@ -1137,63 +1137,8 @@
 er;%0A
-import com.intellij.openapi.application.ModalityState;%0A
 impo
@@ -2778,96 +2778,42 @@
 n().
-invokeLater(new Runnable() %7B%0A          @Override%0A          public void run() %7B%0A 
+assertIsDispatchThread();%0A
         
    N
@@ -2808,19 +2808,16 @@
         
-   
 Navigata
@@ -2846,27 +2846,24 @@
 lement;%0A
-%0A  
         
   //this
@@ -2854,18 +2854,16 @@
         
-  
 //this i
@@ -2895,28 +2895,24 @@
 ion%0A        
-   
- 
 if (element 
@@ -2929,28 +2929,24 @@
  PsiFile) %7B%0A
-    
           Vi
@@ -3005,28 +3005,24 @@
 ;%0A          
-    
 if (file == 
@@ -3045,20 +3045,16 @@
         
-  
-  
 OpenFile
@@ -3178,20 +3178,16 @@
         
-    
 n = desc
@@ -3262,20 +3262,16 @@
         
-    
 %7D%0A%0A     
@@ -3273,25 +3273,20 @@
         
- 
-   
 if (
-!
 n.canNav
@@ -3294,26 +3294,18 @@
 gate()) 
-return;%0A  
+%7B%0A
         
@@ -3336,48 +3336,9 @@
     
-  %7D%0A        %7D, ModalityState.NON_MODAL);
+%7D
 %0A   

Fix Shift+Enter shortcut in Go to file popup