mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ReadonlyStatusHandler refactored
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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<VirtualFile> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-4
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+5
-12
@@ -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;
|
||||
|
||||
+44
-30
@@ -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<FileInfo>(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<VirtualFile> readOnlyFiles = new ArrayList<VirtualFile>();
|
||||
List<VirtualFile> updatedFiles = new ArrayList<VirtualFile>();
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user