diff --git a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java index b1f9195567ef..b79ace0fa51a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java @@ -6,7 +6,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; @@ -70,29 +69,24 @@ public class CodeInsightUtilBase { language); } - public static boolean prepareFileForWrite(final PsiFile file) { - if (file == null) return false; + public static boolean prepareFileForWrite(final PsiFile psiFile) { + if (psiFile == null) return false; + final VirtualFile file = psiFile.getVirtualFile(); + final Project project = psiFile.getProject(); - final Project project = file.getProject(); - final Document document = PsiDocumentManager.getInstance(project).getDocument(file); - - if (!ReadonlyStatusHandler.getInstance(project).isWriteAccessAllowed(file.getVirtualFile())) { - - final Editor editor = - FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file.getVirtualFile()), true); - - if (!FileDocumentManager.getInstance().requestWriting(document, project)) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - if (editor != null && editor.getComponent().isDisplayable()) { - HintManager.getInstance() - .showErrorHint(editor, CodeInsightBundle.message("error.hint.file.is.readonly", file.getVirtualFile().getPresentableUrl())); - } + final Editor editor = + psiFile.isWritable() ? null : FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file), true); + if (!ReadonlyStatusHandler.ensureFilesWritable(project, file)) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (editor != null && editor.getComponent().isDisplayable()) { + HintManager.getInstance() + .showErrorHint(editor, CodeInsightBundle.message("error.hint.file.is.readonly", file.getPresentableUrl())); } - }); + } + }); - return false; - } + return false; } return true; diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java index ed33c1f07c05..5e7ee8549aa9 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java @@ -60,12 +60,6 @@ public abstract class FileDocumentManager { @NotNull public abstract String getLineSeparator(@Nullable VirtualFile file, @Nullable Project project); - /** - * @return true if writing access allowed - * @see #requestWriting(com.intellij.openapi.editor.Document, com.intellij.openapi.project.Project) - */ - public abstract boolean isWritingAllowed(@NotNull Document document, Project project); - /** * Requests writing access on given document, possibly involving interaction with user. * diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java b/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java index 007672065f03..7c4ad3705eb3 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java @@ -15,67 +15,27 @@ */ package com.intellij.openapi.vfs; -import com.intellij.CommonBundle; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.NotNull; import java.util.Collection; public abstract class ReadonlyStatusHandler { - public static boolean ensureFilesWritable(Project project, @NotNull VirtualFile... files) { + public static boolean ensureFilesWritable(Project project, VirtualFile... files) { return getInstance(project).ensureFilesWritable(files).hasReadonlyFiles(); } - public static class OperationStatus { - private final VirtualFile[] myReadonlyFiles; - private final VirtualFile[] myUpdatedFiles; + public interface OperationStatus { + VirtualFile[] getReadonlyFiles(); - public OperationStatus(final VirtualFile[] readonlyFiles, final VirtualFile[] updatedFiles) { - myReadonlyFiles = readonlyFiles; - myUpdatedFiles = updatedFiles; - } + boolean hasReadonlyFiles(); - public VirtualFile[] getReadonlyFiles() { - return myReadonlyFiles; - } - - public VirtualFile[] getUpdatedFiles() { - return myUpdatedFiles; - } - - public boolean hasUpdatedFiles() { - return myUpdatedFiles.length > 0; - } - - public boolean hasReadonlyFiles() { - return myReadonlyFiles.length > 0; - } - - public String getReadonlyFilesMessage() { - if (hasReadonlyFiles()) { - StringBuffer buf = new StringBuffer(); - if (myReadonlyFiles.length > 1) { - for (VirtualFile file : myReadonlyFiles) { - buf.append('\n'); - buf.append(file.getPresentableUrl()); - } - - return CommonBundle.message("failed.to.make.the.following.files.writable.error.message", buf.toString()); - } - else { - return CommonBundle.message("failed.to.make.file.writeable.error.message", myReadonlyFiles[0].getPresentableUrl()); - } - } - return null; - } + String getReadonlyFilesMessage(); } public abstract OperationStatus ensureFilesWritable(VirtualFile... files); - public abstract boolean isWriteAccessAllowed(VirtualFile... files); - public OperationStatus ensureFilesWritable(final Collection files) { return ensureFilesWritable(files.toArray(new VirtualFile[files.size()])); } @@ -83,4 +43,5 @@ public abstract class ReadonlyStatusHandler { public static ReadonlyStatusHandler getInstance(Project project) { return ServiceManager.getService(project, ReadonlyStatusHandler.class); } + } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java index 4943849bac7c..a3d33bf4945d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java @@ -638,10 +638,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject } } - if (readonlyFiles.isEmpty()) return new ReadonlyStatusHandler.OperationStatus(VirtualFile.EMPTY_ARRAY, VirtualFile.EMPTY_ARRAY); - - return ReadonlyStatusHandler.getInstance(myProject) - .ensureFilesWritable(readonlyFiles.toArray(new VirtualFile[readonlyFiles.size()])); + return ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(readonlyFiles); } }); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index bc8acc46204a..bf0094a3be31 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -300,21 +300,14 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl } } - @Override - public boolean isWritingAllowed(@NotNull Document document, Project project) { - return document.isWritable(); - } - @Override public boolean requestWriting(@NotNull Document document, Project project) { - if (isWritingAllowed(document, project)) { - return true; + final VirtualFile file = getInstance().getFile(document); + if (file != null && file.isValid()) { + return ReadonlyStatusHandler.ensureFilesWritable(project, file); } - if (project != null) { - final VirtualFile file = getInstance().getFile(document); - if (file != null && file.isValid()) { - return ReadonlyStatusHandler.ensureFilesWritable(project, file); - } + if (document.isWritable()) { + return true; } document.fireReadOnlyModificationAttempt(); return false; diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java index efe19f26b243..b54c608de0ee 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java @@ -41,6 +41,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.CommonBundle; import gnu.trove.THashSet; import java.util.ArrayList; @@ -79,7 +80,7 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements public OperationStatus ensureFilesWritable(VirtualFile... files) { if (files.length == 0) { - return new OperationStatus(VirtualFile.EMPTY_ARRAY, VirtualFile.EMPTY_ARRAY); + return new OperationStatusImpl(VirtualFile.EMPTY_ARRAY); } ApplicationManager.getApplication().assertIsDispatchThread(); @@ -92,18 +93,13 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements } files = realFiles.toArray(new VirtualFile[realFiles.size()]); - final long[] modificationStamps = new long[files.length]; - for (int i = 0; i < files.length; i++) { - modificationStamps[i] = files[i].getModificationStamp(); - } - final FileInfo[] fileInfos = createFileInfos(files); if (fileInfos.length == 0) { // if all files are already writable - return createResultStatus(files, modificationStamps); + return createResultStatus(files); } if (ApplicationManager.getApplication().isUnitTestMode()) { - return createResultStatus(files, modificationStamps); + return createResultStatus(files); } // This event count hack is necessary to allow actions that called this stuff could still get data from their data contexts. @@ -117,38 +113,21 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements processFiles(new ArrayList(Arrays.asList(fileInfos))); // the collection passed is modified } IdeEventQueue.getInstance().setEventCount(savedEventCount); - return createResultStatus(files, modificationStamps); + return createResultStatus(files); } - @Override - public boolean isWriteAccessAllowed(VirtualFile... files) { - for (VirtualFile file : files) { - if (!file.isWritable()) { - return false; - } - } - return true; - } - - private static OperationStatus createResultStatus(final VirtualFile[] files, final long[] modificationStamps) { + private static OperationStatus createResultStatus(final VirtualFile[] files) { List readOnlyFiles = new ArrayList(); - List updatedFiles = new ArrayList(); - for (int i = 0; i < files.length; i++) { - VirtualFile file = files[i]; + for (VirtualFile file : files) { if (file.exists()) { if (!file.isWritable()) { readOnlyFiles.add(file); } - if (modificationStamps[i] != file.getModificationStamp()) { - updatedFiles.add(file); - } } } - return new OperationStatus( - readOnlyFiles.isEmpty() ? VirtualFile.EMPTY_ARRAY : readOnlyFiles.toArray(new VirtualFile[readOnlyFiles.size()]), - updatedFiles.isEmpty() ? VirtualFile.EMPTY_ARRAY : updatedFiles.toArray(new VirtualFile[updatedFiles.size()]) - ); + return new OperationStatusImpl( + readOnlyFiles.isEmpty() ? VirtualFile.EMPTY_ARRAY : readOnlyFiles.toArray(new VirtualFile[readOnlyFiles.size()])); } private FileInfo[] createFileInfos(VirtualFile[] files) { @@ -178,4 +157,39 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements } } } + + private static class OperationStatusImpl implements OperationStatus { + + private final VirtualFile[] myReadonlyFiles; + + OperationStatusImpl(final VirtualFile[] readonlyFiles) { + myReadonlyFiles = readonlyFiles; + } + + public VirtualFile[] getReadonlyFiles() { + return myReadonlyFiles; + } + + public boolean hasReadonlyFiles() { + return myReadonlyFiles.length > 0; + } + + public String getReadonlyFilesMessage() { + if (hasReadonlyFiles()) { + StringBuffer buf = new StringBuffer(); + if (myReadonlyFiles.length > 1) { + for (VirtualFile file : myReadonlyFiles) { + buf.append('\n'); + buf.append(file.getPresentableUrl()); + } + + return CommonBundle.message("failed.to.make.the.following.files.writable.error.message", buf.toString()); + } + else { + return CommonBundle.message("failed.to.make.file.writeable.error.message", myReadonlyFiles[0].getPresentableUrl()); + } + } + throw new RuntimeException("No readonly files"); + } + } }