IDEADEV-34435
[fedora-idea.git] / platform-impl / src / com / intellij / ide / RecentProjectsManagerBase.java
blob9ae91d89e42a94f894ccb5217479097e7d55b6cb
1 package com.intellij.ide;
3 import com.intellij.ide.impl.ProjectUtil;
4 import com.intellij.openapi.actionSystem.AnAction;
5 import com.intellij.openapi.actionSystem.AnActionEvent;
6 import com.intellij.openapi.actionSystem.PlatformDataKeys;
7 import com.intellij.openapi.actionSystem.Separator;
8 import com.intellij.openapi.application.ApplicationManager;
9 import com.intellij.openapi.components.PersistentStateComponent;
10 import com.intellij.openapi.project.Project;
11 import com.intellij.openapi.project.ProjectManager;
12 import com.intellij.openapi.project.ProjectManagerAdapter;
13 import com.intellij.openapi.util.Ref;
14 import com.intellij.openapi.util.SystemInfo;
15 import com.intellij.util.ArrayUtil;
16 import com.intellij.util.messages.MessageBus;
17 import org.jetbrains.annotations.NotNull;
18 import org.jetbrains.annotations.Nullable;
20 import java.io.File;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
25 /**
26 * @author yole
28 public abstract class RecentProjectsManagerBase implements PersistentStateComponent<RecentProjectsManagerBase.State> {
29 public static RecentProjectsManagerBase getInstance() {
30 return ApplicationManager.getApplication().getComponent(RecentProjectsManagerBase.class);
33 public static class State {
34 public List<String> recentPaths = new ArrayList<String>();
35 public String lastPath;
38 protected State myState = new State();
40 private static final int MAX_RECENT_PROJECTS = 15;
42 public RecentProjectsManagerBase(ProjectManager projectManager, MessageBus messageBus) {
43 projectManager.addProjectManagerListener(new MyProjectManagerListener());
44 messageBus.connect().subscribe(AppLifecycleListener.TOPIC, new MyAppLifecycleListener());
47 public State getState() {
48 validateRecentProjects();
49 return myState;
52 public void loadState(final State state) {
53 myState = state;
54 if (myState.lastPath != null && !new File(myState.lastPath).exists()) {
55 myState.lastPath = null;
57 if (myState.lastPath != null) {
58 File lastFile = new File(myState.lastPath);
59 if (lastFile.isDirectory() && !new File(lastFile, ProjectUtil.DIRECTORY_BASED_PROJECT_DIR).exists()) {
60 myState.lastPath = null;
65 private void validateRecentProjects() {
66 for (Iterator i = myState.recentPaths.iterator(); i.hasNext();) {
67 String s = (String)i.next();
68 if (s == null || !(new File(s).exists())) {
69 i.remove();
72 while (myState.recentPaths.size() > MAX_RECENT_PROJECTS) {
73 myState.recentPaths.remove(myState.recentPaths.size() - 1);
77 private void removePath(final String path) {
78 if (SystemInfo.isFileSystemCaseSensitive) {
79 myState.recentPaths.remove(path);
81 else {
82 Iterator<String> i = myState.recentPaths.iterator();
83 while (i.hasNext()) {
84 String p = i.next();
85 if (path.equalsIgnoreCase(p)) {
86 i.remove();
92 public String getLastProjectPath() {
93 return myState.lastPath;
96 public void updateLastProjectPath() {
97 Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
98 if (openProjects.length == 0) {
99 myState.lastPath = null;
100 } else {
101 myState.lastPath = getProjectPath(openProjects[openProjects.length - 1]);
106 * @param addClearListItem - used for detecting whether the "Clear List" action should be added
107 * to the end of the returned list of actions
108 * @return
110 public AnAction[] getRecentProjectsActions(boolean addClearListItem) {
111 validateRecentProjects();
113 Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
115 ArrayList<AnAction> actions = new ArrayList<AnAction>();
116 outer: for (String recentPath : myState.recentPaths) {
118 for (Project openProject : openProjects) {
119 if (recentPath.equals(getProjectPath(openProject))) {
120 continue outer;
124 actions.add(new ReopenProjectAction(recentPath));
128 if (actions.size() == 0) {
129 return new AnAction[0];
132 ArrayList<AnAction> list = new ArrayList<AnAction>();
133 for (AnAction action : actions) {
134 list.add(action);
136 if (addClearListItem) {
137 AnAction clearListAction = new AnAction(IdeBundle.message("action.clear.list")) {
138 public void actionPerformed(AnActionEvent e) {
139 myState.recentPaths.clear();
142 list.add(Separator.getInstance());
143 list.add(clearListAction);
146 return list.toArray(new AnAction[list.size()]);
149 public String[] getRecentProjectPaths() {
150 validateRecentProjects();
151 return ArrayUtil.toStringArray(myState.recentPaths);
154 @Nullable
155 protected abstract String getProjectPath(Project project);
157 protected abstract void doOpenProject(String projectPath, Project projectToClose);
159 private class MyProjectManagerListener extends ProjectManagerAdapter {
160 public void projectOpened(final Project project) {
161 String path = getProjectPath(project);
162 myState.lastPath = path;
163 removePath(path);
164 myState.recentPaths.add(0, path);
167 public void projectClosed(final Project project) {
168 Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
169 if (openProjects.length > 0) {
170 String path = getProjectPath(openProjects[openProjects.length - 1]);
171 if (path != null) {
172 myState.lastPath = path;
173 removePath(path);
174 myState.recentPaths.add(0, path);
180 private class ReopenProjectAction extends AnAction {
181 private final String myProjectPath;
183 public ReopenProjectAction(String projectPath) {
184 myProjectPath = projectPath;
185 getTemplatePresentation().setText(projectPath, false);
188 public void actionPerformed(AnActionEvent e) {
189 doOpenProject(myProjectPath, PlatformDataKeys.PROJECT.getData(e.getDataContext()));
193 private class MyAppLifecycleListener extends AppLifecycleListener.Adapter {
194 public void appFrameCreated(final String[] commandLineArgs, @NotNull final Ref<Boolean> willOpenProject) {
195 if (GeneralSettings.getInstance().isReopenLastProject() && getLastProjectPath() != null) {
196 willOpenProject.set(Boolean.TRUE);
200 public void appStarting(final Project projectFromCommandLine) {
201 if (projectFromCommandLine != null) return;
202 GeneralSettings generalSettings = GeneralSettings.getInstance();
203 if (generalSettings.isReopenLastProject()) {
204 String lastProjectPath = getLastProjectPath();
205 if (lastProjectPath != null) {
206 doOpenProject(lastProjectPath, null);
211 public void projectFrameClosed() {
212 updateLastProjectPath();
215 public void projectOpenFailed() {
216 updateLastProjectPath();