Merge remote-tracking branch 'origin/master'

This commit is contained in:
Anna Kozlova
2012-09-04 11:40:23 +04:00
11 changed files with 113 additions and 79 deletions
@@ -23,6 +23,7 @@ import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
@State(
name = "RecentProjectsManager",
@@ -37,11 +38,11 @@ public class RecentProjectsManager extends RecentProjectsManagerBase {
super(projectManager, messageBus);
}
protected String getProjectPath(Project project) {
protected String getProjectPath(@NotNull Project project) {
return project.getPresentableUrl();
}
protected void doOpenProject(final String projectPath, Project projectToClose, final boolean forceOpenInNewFrame) {
protected void doOpenProject(@NotNull String projectPath, Project projectToClose, boolean forceOpenInNewFrame) {
ProjectUtil.openProject(projectPath, projectToClose, forceOpenInNewFrame);
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2012 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.psi.codeStyle.arrangement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* The whole arrangement idea is to allow to change file entries order according to the user-provided rules.
* <p/>
* That means that we can re-use the same mechanism during, say, new members generation - arrangement rules can be used to
* determine position where a new element should be inserted.
* <p/>
* This service provides utility methods for that.
*
* @author Denis Zhdanov
* @since 9/4/12 11:12 AM
*/
public class MemberOrderService {
public static final int UNDEFINED_WEIGHT = -1;
/**
* Allows to get a given member's weight according to the
* {@link CommonCodeStyleSettings#getArrangementRules() user-defined arrangement rules}.
* <p/>
* That means that we can call this method for different members and derive their relative order by comparing their weights.
*
* @param member target member which weight should be calculated
* @param settings code style settings to use
* @param context given member's context (if any). Is useful when we have, say, an existing class and want to know where
* to insert a new field. Not only 'by type' filtering might be exploited (like 'fields before methods') but
* 'by name' as well, i.e. we want to insert a new field to the 'fidles' group and define its position
* according to the lexicographical fields order
* @return given member's weight if the one can be computed;
* {@link #UNDEFINED_WEIGHT} otherwise
*/
public int getMemberOrderWeight(@NotNull PsiElement member, @NotNull CommonCodeStyleSettings settings, @Nullable PsiElement context) {
// TODO den implement
return UNDEFINED_WEIGHT;
}
}
@@ -39,6 +39,11 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* Encapsulates generic functionality of arranging file elements by the predefined rules.
* <p/>
* I.e. the general idea is to have a language-specific rules hidden by generic arrangement API and common arrangement
* engine which works on top of that API and performs the arrangement.
*
* @author Denis Zhdanov
* @since 7/20/12 1:56 PM
*/
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -713,9 +714,17 @@ public class VfsUtil extends VfsUtilCore {
return index < 0 ? null : urlOrPath.substring(index+1);
}
public static void markDirtyAndRefresh(boolean async, boolean recursive, VirtualFile... files) {
List<VirtualFile> list = ContainerUtil.newArrayList(files);
public static void markDirtyAndRefresh(boolean async, boolean recursive, boolean loadChildren, VirtualFile... files) {
List<VirtualFile> list = ContainerUtil.filter(Condition.NOT_NULL, files);
if (list.isEmpty()) {
return;
}
for (VirtualFile file : list) {
if (loadChildren) {
file.getChildren();
}
if (file instanceof NewVirtualFile) {
if (recursive) {
((NewVirtualFile)file).markDirtyRecursively();
@@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.PlatformProjectOpenProcessor;
import com.intellij.platform.ProjectBaseDirectory;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -46,16 +47,13 @@ public class RecentDirectoryProjectsManager extends RecentProjectsManagerBase {
}
@Nullable
protected String getProjectPath(final Project project) {
protected String getProjectPath(@NotNull Project project) {
final ProjectBaseDirectory baseDir = ProjectBaseDirectory.getInstance(project);
VirtualFile baseDirVFile = baseDir.getBaseDir() != null ? baseDir.getBaseDir() : project.getBaseDir();
if (baseDirVFile != null) {
return FileUtil.toSystemDependentName(baseDirVFile.getPath());
}
return null;
final VirtualFile baseDirVFile = baseDir.getBaseDir() != null ? baseDir.getBaseDir() : project.getBaseDir();
return baseDirVFile != null ? FileUtil.toSystemDependentName(baseDirVFile.getPath()) : null;
}
protected void doOpenProject(final String projectPath, final Project projectToClose, final boolean forceOpenInNewFrame) {
protected void doOpenProject(@NotNull String projectPath, Project projectToClose, boolean forceOpenInNewFrame) {
final VirtualFile projectDir = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(projectPath));
if (projectDir != null) {
PlatformProjectOpenProcessor.doOpenProject(projectDir, projectToClose, forceOpenInNewFrame, -1, null, true);
@@ -230,13 +230,13 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
}
@Nullable
protected abstract String getProjectPath(Project project);
protected abstract String getProjectPath(@NotNull Project project);
protected abstract void doOpenProject(String projectPath, Project projectToClose, final boolean forceOpenInNewFrame);
protected abstract void doOpenProject(@NotNull String projectPath, @Nullable Project projectToClose, boolean forceOpenInNewFrame);
public static boolean isValidProjectPath(String projectPath) {
final File file = new File(projectPath);
return file.exists() && (!file.isDirectory() || new File(file, ProjectUtil.DIRECTORY_BASED_PROJECT_DIR).exists());
return file.exists() && (!file.isDirectory() || new File(file, Project.DIRECTORY_STORE_FOLDER).exists());
}
private class MyProjectManagerListener extends ProjectManagerAdapter {
@@ -310,7 +310,9 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
List<String> openPaths = myState.openPaths;
if (!openPaths.isEmpty()) {
for (String openPath : openPaths) {
if (isValidProjectPath(openPath)) doOpenProject(openPath, null, true);
if (isValidProjectPath(openPath)) {
doOpenProject(openPath, null, true);
}
}
}
else {
@@ -29,7 +29,6 @@ import com.intellij.openapi.options.StreamProvider;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
import com.intellij.util.io.fs.FileSystem;
import com.intellij.util.io.fs.IFile;
@@ -86,8 +85,6 @@ public class FileBasedStorage extends XmlElementStorage {
VirtualFileTracker virtualFileTracker = (VirtualFileTracker)picoContainer.getComponentInstanceOfType(VirtualFileTracker.class);
MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class);
if (virtualFileTracker != null && messageBus != null) {
final String path = myFile.getAbsolutePath();
final String fileUrl = LocalFileSystem.PROTOCOL_PREFIX + path.replace(File.separatorChar, '/');
@@ -114,17 +111,11 @@ public class FileBasedStorage extends XmlElementStorage {
}
}
public static void syncRefreshPathRecursively(String configDirectoryPath, @Nullable final String excludeDir) {
private static void syncRefreshPathRecursively(@NotNull String configDirectoryPath, @Nullable final String excludeDir) {
VirtualFile configDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(configDirectoryPath);
if (configDir != null) {
requestAllChildren(configDir, excludeDir);
if (configDir instanceof NewVirtualFile) {
((NewVirtualFile)configDir).markDirtyRecursively();
}
configDir.refresh(false, true);
VfsUtil.markDirtyAndRefresh(false, true, false, configDir);
}
}
@@ -188,7 +179,8 @@ public class FileBasedStorage extends XmlElementStorage {
boolean needsSave = needsSave();
if (needsSave) {
if (LOG.isDebugEnabled()) {
LOG.info("File " + myFileSpec + " needs save; hash=" + myUpToDateHash + "; currentHash=" + calcHash() + "; content needs save=" + physicalContentNeedsSave());
LOG.info("File " + myFileSpec + " needs save; hash=" + myUpToDateHash + "; currentHash=" + calcHash() + "; " +
"content needs save=" + physicalContentNeedsSave());
}
return getAllStorageFiles();
}
@@ -201,7 +193,6 @@ public class FileBasedStorage extends XmlElementStorage {
public List<IFile> getAllStorageFiles() {
return Collections.singletonList(myFile);
}
}
@Override
@@ -162,34 +162,35 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}
final StateStorageManager stateStorageManager = getStateStorageManager();
final LocalFileSystem fs = LocalFileSystem.getInstance();
final File file = new File(filePath);
if (!isIprPath(file)) {
myScheme = StorageScheme.DIRECTORY_BASED;
final File dirStore = file.isDirectory() ? new File(file, Project.DIRECTORY_STORE_FOLDER)
: new File(file.getParentFile(), Project.DIRECTORY_STORE_FOLDER);
FileBasedStorage.syncRefreshPathRecursively(dirStore.getPath(), null);
myScheme = StorageScheme.DIRECTORY_BASED;
stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.PROJECT_FILE), new File(dirStore, "misc.xml").getPath());
final File ws = new File(dirStore, "workspace.xml");
stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.WORKSPACE_FILE), ws.getPath());
if (!ws.exists() && !file.isDirectory()) {
useOldWsContent(filePath, ws);
}
stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.PROJECT_CONFIG_DIR), dirStore.getPath());
VfsUtil.markDirtyAndRefresh(false, true, true, fs.refreshAndFindFileByIoFile(dirStore));
}
else {
LocalFileSystem.getInstance().refreshAndFindFileByPath(filePath);
myScheme = StorageScheme.DEFAULT;
stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.PROJECT_FILE), filePath);
final String workspacePath = composeWsPath(filePath);
LocalFileSystem.getInstance().refreshAndFindFileByPath(workspacePath);
stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.WORKSPACE_FILE), workspacePath);
VfsUtil.markDirtyAndRefresh(false, true, false, fs.refreshAndFindFileByPath(filePath), fs.refreshAndFindFileByPath(workspacePath));
}
myCachedLocation = null;
@@ -197,8 +198,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}
private static boolean isIprPath(final File file) {
final String name = file.getName();
return name.indexOf(".") > 0 && ProjectFileType.DEFAULT_EXTENSION.equals(FileUtil.getExtension(name));
return ProjectFileType.DEFAULT_EXTENSION.equals(FileUtil.getExtension(file.getName()));
}
private static String composeWsPath(String filePath) {
@@ -283,7 +283,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
public String getProjectName() {
if (myScheme == StorageScheme.DIRECTORY_BASED) {
final VirtualFile baseDir = getProjectBaseDir();
assert baseDir != null : "project file: " + getProjectFile();
assert baseDir != null : "scheme=" + myScheme + " project file=" + getProjectFilePath();
final VirtualFile ideaDir = baseDir.findChild(Project.DIRECTORY_STORE_FOLDER);
if (ideaDir != null && ideaDir.isValid()) {
@@ -18,7 +18,6 @@ package com.intellij.openapi.project.impl;
import com.intellij.conversion.ConversionResult;
import com.intellij.conversion.ConversionService;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.ide.highlighter.WorkspaceFileType;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.notification.NotificationsManager;
@@ -39,7 +38,10 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.project.ProjectReloadState;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.startup.StartupManager;
@@ -52,7 +54,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.VirtualFileManagerListener;
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.openapi.wm.impl.WindowManagerImpl;
@@ -288,8 +289,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
private ProjectImpl createProject(@Nullable String projectName, @Nullable String filePath, boolean isDefault, boolean isOptimiseTestLoadSpeed) {
return isDefault ? new DefaultProject(this, filePath, isOptimiseTestLoadSpeed, projectName) :
new ProjectImpl(this, filePath, isOptimiseTestLoadSpeed, projectName);
assert isDefault || filePath != null : filePath;
return isDefault ? new DefaultProject(this, null, isOptimiseTestLoadSpeed, projectName)
: new ProjectImpl(this, filePath, isOptimiseTestLoadSpeed, projectName);
}
private static void scheduleDispose(final ProjectImpl project) {
@@ -471,7 +473,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
@Override
public Project loadAndOpenProject(@NotNull final String filePath) throws IOException {
final Project project = convertAndLoadProject(filePath);
if (project == null) {
showWelcomeScreenIfNoProjectOpened();
@@ -487,6 +488,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
});
}
return project;
}
@@ -535,8 +537,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
*/
@Nullable
private Project loadProjectWithProgress(@NotNull final String filePath) throws IOException {
refreshProjectFiles(filePath);
final ProjectImpl project = createProject(null, canonicalize(filePath), false, false);
try {
myProgressManager.runProcessWithProgressSynchronously(new ThrowableComputable<Project, IOException>() {
@@ -558,36 +558,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
return project;
}
private static void refreshProjectFiles(final String filePath) {
if (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isDispatchThread()) {
final File file = new File(filePath);
if (file.isFile()) {
VirtualFile projectFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(filePath);
if (projectFile != null) {
projectFile.refresh(false, false);
}
File iwsFile = new File(file.getParentFile(), FileUtil.getNameWithoutExtension(file) + WorkspaceFileType.DOT_DEFAULT_EXTENSION);
VirtualFile wsFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(iwsFile);
if (wsFile != null) {
wsFile.refresh(false, false);
}
}
else {
VirtualFile projectConfigDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(filePath, Project.DIRECTORY_STORE_FOLDER));
if (projectConfigDir != null && projectConfigDir.isDirectory()) {
projectConfigDir.getChildren();
if (projectConfigDir instanceof NewVirtualFile) {
((NewVirtualFile)projectConfigDir).markDirtyRecursively();
}
projectConfigDir.refresh(false, true);
}
}
}
}
private static void notifyProjectOpenFailed() {
ApplicationManager.getApplication().getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).projectOpenFailed();
}
@@ -595,11 +565,11 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
private void registerExternalProjectFileListener(VirtualFileManagerEx virtualFileManager) {
virtualFileManager.addVirtualFileManagerListener(new VirtualFileManagerListener() {
@Override
public void beforeRefreshStart(boolean asynchonous) {
public void beforeRefreshStart(boolean asynchronous) {
}
@Override
public void afterRefreshFinish(boolean asynchonous) {
public void afterRefreshFinish(boolean asynchronous) {
scheduleReloadApplicationAndProject();
}
});
@@ -182,6 +182,7 @@
serviceImplementation="com.intellij.openapi.roots.impl.libraries.JarDirectoryWatcherFactoryImpl"/>
<applicationService serviceImplementation="com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine"/>
<applicationService serviceImplementation="com.intellij.psi.codeStyle.arrangement.MemberOrderService"/>
<projectService serviceInterface="com.intellij.ui.EditorTextFieldProvider"
serviceImplementation="com.intellij.ui.EditorTextFieldProviderImpl"/>
@@ -33,7 +33,7 @@ import java.awt.*;
*/
public class MultiRowFlowPanel extends JPanel {
private final int maximumWidth = Toolkit.getDefaultToolkit().getScreenSize().width / 2;
private final int maximumWidth = GraphicsEnvironment.isHeadless() ? 400 : Toolkit.getDefaultToolkit().getScreenSize().width / 2;
public MultiRowFlowPanel(@JdkConstants.FlowLayoutAlignment int align, int hGap, int vGap) {
super(new FlowLayout(align, getGapToUse(hGap), getGapToUse(vGap)));