diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
index 60b05dae04a7..aa1a1a98f93a 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.command.undo.UndoableAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
@@ -537,22 +538,20 @@ public abstract class BaseRefactoringProcessor implements Runnable {
public final void run() {
if (ApplicationManager.getApplication().isUnitTestMode()) {
ApplicationManager.getApplication().assertIsDispatchThread();
- doRun();
+ NonProjectFileWritingAccessProvider.disableChecksDuring(this::doRun);
+
+ //noinspection TestOnlyProblems
UIUtil.dispatchAllInvocationEvents();
+ //noinspection TestOnlyProblems
UIUtil.dispatchAllInvocationEvents();
return;
}
if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
LOG.error("Refactorings should not be started inside write action\n because they start progress inside and any read action from the progress task would cause the deadlock", new Exception());
- DumbService.getInstance(myProject).smartInvokeLater(new Runnable() {
- @Override
- public void run() {
- doRun();
- }
- });
+ DumbService.getInstance(myProject).smartInvokeLater(() -> NonProjectFileWritingAccessProvider.disableChecksDuring(this::doRun));
}
else {
- doRun();
+ NonProjectFileWritingAccessProvider.disableChecksDuring(this::doRun);
}
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
index ede322cb6ef4..efcce0243dfb 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
@@ -142,7 +142,7 @@ public class PsiElementRenameHandler implements RenameHandler {
if (!PsiManager.getInstance(project).isInProject(element)) {
if (element.isPhysical()) {
VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element);
- if (!(virtualFile != null && NonProjectFileWritingAccessProvider.isWriteAccessAllowedExplicitly(virtualFile, project))) {
+ if (!(virtualFile != null && NonProjectFileWritingAccessProvider.isWriteAccessAllowed(virtualFile))) {
String message = RefactoringBundle.message("error.out.of.project.element", UsageViewUtil.getType(element));
return RefactoringBundle.getCannotRefactorMessage(message);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
index 5e0be6d90835..06bd381c3f96 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorProvider;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
+import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.project.DumbAware;
@@ -41,7 +42,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.impl.welcomeScreen.NewWelcomeScreen;
import com.intellij.platform.PlatformProjectOpenProcessor;
import com.intellij.projectImport.ProjectAttachProcessor;
-import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -127,6 +127,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
return;
}
+ NonProjectFileWritingAccessProvider.allowWriting(file);
+
OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.form b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.form
index 01173794cbeb..edb8c4e4be4e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.form
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.form
@@ -8,39 +8,48 @@
-
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
-
+
@@ -64,6 +73,7 @@
+
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.java
index 397ff73da184..6562b6bd4627 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessDialog.java
@@ -17,33 +17,85 @@ package com.intellij.openapi.fileEditor.impl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.readOnlyHandler.FileListRenderer;
+import com.intellij.openapi.vcs.readOnlyHandler.ReadOnlyStatusDialog;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CollectionListModel;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
import java.util.List;
public class NonProjectFileWritingAccessDialog extends DialogWrapper {
private JPanel myPanel;
+ private JLabel myListTitle;
private JList myFileList;
+ private JRadioButton myUnlockOneButton;
+ private JRadioButton myUnlockDirButton;
private JRadioButton myUnlockAllButton;
- protected NonProjectFileWritingAccessDialog(@NotNull Project project, @NotNull List nonProjectFiles) {
+ public NonProjectFileWritingAccessDialog(@NotNull Project project, @NotNull List nonProjectFiles) {
+ this(project, nonProjectFiles, "Non-Project Files");
+ }
+
+ public NonProjectFileWritingAccessDialog(@NotNull Project project,
+ @NotNull List nonProjectFiles,
+ @NotNull String filesType) {
super(project);
- setTitle("Non-Project Files Access");
+ setTitle(filesType + " Protection");
myFileList.setCellRenderer(new FileListRenderer());
myFileList.setModel(new CollectionListModel(nonProjectFiles));
+
+ String theseFilesMessage = ReadOnlyStatusDialog.getTheseFilesMessage(nonProjectFiles);
+ myListTitle.setText(StringUtil.capitalize(theseFilesMessage)
+ + " " + (nonProjectFiles.size() > 1 ? "do" : "does")
+ + " not belong to the project:");
+
+
+ myUnlockOneButton.setSelected(true);
+ setTextAndMnemonicAndListeners(myUnlockOneButton, "I want to edit " + theseFilesMessage + " anyway", "edit");
+
+ int dirs = ContainerUtil.map2Set(nonProjectFiles, VirtualFile::getParent).size();
+ setTextAndMnemonicAndListeners(myUnlockDirButton, "I want to edit all files in "
+ + StringUtil.pluralize("this", dirs)
+ + " " + StringUtil.pluralize("directory", dirs), "dir");
+
+ setTextAndMnemonicAndListeners(myUnlockAllButton, "I want to edit any non-project file in the current session", "any");
+
+ // disable default button to avoid accidental pressing, if user typed something, missed the dialog and pressed 'enter'.
getOKAction().putValue(DEFAULT_ACTION, null);
- getCancelAction().putValue(DEFAULT_ACTION, true);
-
+ getCancelAction().putValue(DEFAULT_ACTION, null);
+
+ getRootPane().registerKeyboardAction(e -> doOKAction(), KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK),
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ getRootPane().registerKeyboardAction(e -> doOKAction(), KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_DOWN_MASK),
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+
init();
}
+ private void setTextAndMnemonicAndListeners(JRadioButton button, String text, String mnemonic) {
+ button.setText(text);
+ button.setMnemonic(mnemonic.charAt(0));
+ button.setDisplayedMnemonicIndex(button.getText().indexOf(mnemonic));
+
+ // enabled OK button when user selects an option
+ button.addActionListener(e -> button.getRootPane().setDefaultButton(getButton(getOKAction())));
+ button.addItemListener(e -> button.getRootPane().setDefaultButton(getButton(getOKAction())));
+ }
+
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myUnlockOneButton;
+ }
@Nullable
@Override
@@ -53,8 +105,9 @@ public class NonProjectFileWritingAccessDialog extends DialogWrapper {
@NotNull
public NonProjectFileWritingAccessProvider.UnlockOption getUnlockOption() {
- return myUnlockAllButton.isSelected() ? NonProjectFileWritingAccessProvider.UnlockOption.UNLOCK_ALL
- : NonProjectFileWritingAccessProvider.UnlockOption.UNLOCK;
+ if (myUnlockAllButton.isSelected()) return NonProjectFileWritingAccessProvider.UnlockOption.UNLOCK_ALL;
+ if (myUnlockDirButton.isSelected()) return NonProjectFileWritingAccessProvider.UnlockOption.UNLOCK_DIR;
+ return NonProjectFileWritingAccessProvider.UnlockOption.UNLOCK;
}
protected String getHelpId() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
index 80fd36ffae83..c7c862519c3c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
@@ -15,8 +15,8 @@
*/
package com.intellij.openapi.fileEditor.impl;
-import com.intellij.ProjectTopics;
import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceKt;
import com.intellij.openapi.components.impl.stores.IProjectStore;
@@ -24,31 +24,35 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ex.ProjectEx;
-import com.intellij.openapi.roots.ModuleRootAdapter;
-import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyKey;
+import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.*;
-import com.intellij.util.NotNullFunction;
+import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.util.NullableFunction;
-import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
-import java.util.*;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class NonProjectFileWritingAccessProvider extends WritingAccessProvider {
- public enum AccessStatus {REQUESTED, ALLOWED}
-
private static final Key ENABLE_IN_TESTS = Key.create("NON_PROJECT_FILE_ACCESS_ENABLE_IN_TESTS");
- private static final Key ALL_ACCESS_ALLOWED = Key.create("NON_PROJECT_FILE_ALL_ACCESS_STATUS");
- private static final NotNullLazyKey
-
+
-
+
-
+
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictDialog.java
index cba973307ca5..e8d9b2a96312 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictDialog.java
@@ -18,11 +18,13 @@ package com.intellij.openapi.vcs.changes.conflicts;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vcs.readOnlyHandler.FileListRenderer;
+import com.intellij.openapi.vcs.readOnlyHandler.ReadOnlyStatusDialog;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CollectionListModel;
import org.jetbrains.annotations.NotNull;
@@ -42,6 +44,7 @@ public class ChangelistConflictDialog extends DialogWrapper {
private JRadioButton myMoveChangesToActiveRadioButton;
private JRadioButton mySwitchToChangelistRadioButton;
private JRadioButton myIgnoreRadioButton;
+ private JLabel myListTitle;
private JList myFileList;
private final Project myProject;
@@ -51,6 +54,10 @@ public class ChangelistConflictDialog extends DialogWrapper {
myProject = project;
setTitle("Resolve Changelist Conflict");
+
+ myListTitle.setText(StringUtil.capitalize(ReadOnlyStatusDialog.getTheseFilesMessage(conflicts))
+ + " " + (conflicts.size() > 1 ? "do" : "does")
+ + " not belong to the active changelist:");
myFileList.setCellRenderer(new FileListRenderer());
myFileList.setModel(new CollectionListModel(conflicts));