IDEA-109618 (show ignored files in Open Project chooser)
[idea/community.git] / platform / platform-impl / src / com / intellij / ide / actions / OpenFileAction.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.icons.AllIcons;
19 import com.intellij.ide.IdeBundle;
20 import com.intellij.ide.impl.ProjectUtil;
21 import com.intellij.openapi.actionSystem.AnAction;
22 import com.intellij.openapi.actionSystem.AnActionEvent;
23 import com.intellij.openapi.application.ApplicationNamesInfo;
24 import com.intellij.openapi.fileChooser.FileChooser;
25 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
26 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
27 import com.intellij.openapi.fileChooser.PathChooserDialog;
28 import com.intellij.openapi.fileChooser.impl.FileChooserUtil;
29 import com.intellij.openapi.fileEditor.FileEditorManager;
30 import com.intellij.openapi.fileEditor.FileEditorProvider;
31 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
32 import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
33 import com.intellij.openapi.fileTypes.FileType;
34 import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
35 import com.intellij.openapi.project.DumbAware;
36 import com.intellij.openapi.project.Project;
37 import com.intellij.openapi.ui.Messages;
38 import com.intellij.openapi.vfs.LocalFileSystem;
39 import com.intellij.openapi.vfs.VfsUtil;
40 import com.intellij.openapi.vfs.VirtualFile;
41 import com.intellij.openapi.wm.impl.welcomeScreen.NewWelcomeScreen;
42 import com.intellij.platform.PlatformProjectOpenProcessor;
43 import com.intellij.projectImport.ProjectAttachProcessor;
44 import com.intellij.util.Consumer;
45 import org.jetbrains.annotations.NotNull;
46 import org.jetbrains.annotations.Nullable;
47
48 import java.util.List;
49
50 public class OpenFileAction extends AnAction implements DumbAware {
51   @Override
52   public void actionPerformed(@NotNull AnActionEvent e) {
53     final Project project = e.getProject();
54     final boolean showFiles = project != null || PlatformProjectOpenProcessor.getInstanceIfItExists() != null;
55     final FileChooserDescriptor descriptor = showFiles ? new ProjectOrFileChooserDescriptor() : new ProjectOnlyFileChooserDescriptor();
56     descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, showFiles);
57
58     FileChooser.chooseFiles(descriptor, project, VfsUtil.getUserHomeDir(), new Consumer<List<VirtualFile>>() {
59       @Override
60       public void consume(final List<VirtualFile> files) {
61         for (VirtualFile file : files) {
62           if (!descriptor.isFileSelectable(file)) {
63             String message = IdeBundle.message("error.dir.contains.no.project", file.getPresentableUrl());
64             Messages.showInfoMessage(project, message, IdeBundle.message("title.cannot.open.project"));
65             return;
66           }
67         }
68         doOpenFile(project, files);
69       }
70     });
71   }
72
73   @Override
74   public void update(@NotNull AnActionEvent e) {
75     if (NewWelcomeScreen.isNewWelcomeScreen(e)) {
76       e.getPresentation().setIcon(AllIcons.Welcome.OpenProject);
77     }
78   }
79
80   private static void doOpenFile(@Nullable Project project, @NotNull List<VirtualFile> result) {
81     for (VirtualFile file : result) {
82       if (file.isDirectory()) {
83         Project openedProject;
84         if (ProjectAttachProcessor.canAttachToProject()) {
85           openedProject = PlatformProjectOpenProcessor.doOpenProject(file, project, false, -1, null, false);
86         }
87         else {
88           openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
89         }
90         FileChooserUtil.setLastOpenedFile(openedProject, file);
91         return;
92       }
93
94       // try to open as a project - unless the file is an .ipr of the current one
95       if ((project == null || !file.equals(project.getProjectFile())) && OpenProjectFileChooserDescriptor.isProjectFile(file)) {
96         Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
97         if (openedProject != null) {
98           FileChooserUtil.setLastOpenedFile(openedProject, file);
99           return;
100         }
101       }
102
103       FileType type = FileTypeChooser.getKnownFileTypeOrAssociate(file, project);
104       if (type == null) return;
105
106       if (project != null) {
107         openFile(file, project);
108       }
109       else {
110         PlatformProjectOpenProcessor processor = PlatformProjectOpenProcessor.getInstanceIfItExists();
111         if (processor != null) {
112           processor.doOpenProject(file, null, false);
113         }
114       }
115     }
116   }
117
118   public static void openFile(String filePath, @NotNull Project project) {
119     VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
120     if (file != null && file.isValid()) {
121       openFile(file, project);
122     }
123   }
124
125   public static void openFile(VirtualFile file, @NotNull Project project) {
126     FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(project, file);
127     if (providers.length == 0) {
128       String message = IdeBundle.message("error.files.of.this.type.cannot.be.opened", ApplicationNamesInfo.getInstance().getProductName());
129       Messages.showErrorDialog(project, message, IdeBundle.message("title.cannot.open.file"));
130       return;
131     }
132
133     OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
134     FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
135   }
136
137   private static class ProjectOnlyFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
138     public ProjectOnlyFileChooserDescriptor() {
139       super(true);
140       setTitle(IdeBundle.message("title.open.project"));
141     }
142   }
143
144   // vanilla OpenProjectFileChooserDescriptor only accepts project files; this one is overridden to accept any files
145   private static class ProjectOrFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
146     private final FileChooserDescriptor myStandardDescriptor =
147       FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withHideIgnored(false);
148
149     public ProjectOrFileChooserDescriptor() {
150       super(true);
151       setTitle(IdeBundle.message("title.open.file.or.project"));
152     }
153
154     @Override
155     public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
156       return file.isDirectory() ? super.isFileVisible(file, showHiddenFiles) : myStandardDescriptor.isFileVisible(file, showHiddenFiles);
157     }
158
159     @Override
160     public boolean isFileSelectable(VirtualFile file) {
161       return file.isDirectory() ? super.isFileSelectable(file) : myStandardDescriptor.isFileSelectable(file);
162     }
163
164     @Override
165     public boolean isChooseMultiple() {
166       return true;
167     }
168   }
169 }