mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
undo: refactored actions
This commit is contained in:
@@ -23,9 +23,8 @@ import com.intellij.ide.projectView.impl.nodes.PackageElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.undo.DocumentReference;
|
||||
import com.intellij.openapi.command.undo.GlobalUndoableAction;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -169,7 +168,7 @@ public class PsiPackageImpl extends PsiElementBase implements PsiPackage, Querya
|
||||
final String oldQualifedName = myQualifiedName;
|
||||
final boolean anyChanged = changePackagePrefixes(oldQualifedName, newQualifiedName);
|
||||
if (anyChanged) {
|
||||
UndoManager.getInstance(myManager.getProject()).undoableActionPerformed(new UndoableAction() {
|
||||
UndoManager.getInstance(myManager.getProject()).undoableActionPerformed(new GlobalUndoableAction() {
|
||||
public void undo() {
|
||||
changePackagePrefixes(newQualifiedName, oldQualifedName);
|
||||
}
|
||||
@@ -177,14 +176,6 @@ public class PsiPackageImpl extends PsiElementBase implements PsiPackage, Querya
|
||||
public void redo() {
|
||||
changePackagePrefixes(oldQualifedName, newQualifiedName);
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return DocumentReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
package com.intellij.psi.impl.source;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.command.undo.DocumentReference;
|
||||
import com.intellij.openapi.command.undo.DocumentReferenceManager;
|
||||
import com.intellij.openapi.command.undo.BasicUndoableAction;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
@@ -237,24 +235,19 @@ public class PsiCodeFragmentImpl extends PsiFileImpl implements JavaCodeFragment
|
||||
//}
|
||||
}
|
||||
|
||||
private static class ImportClassUndoableAction implements UndoableAction {
|
||||
private static class ImportClassUndoableAction extends BasicUndoableAction {
|
||||
private final String myClassName;
|
||||
private final String myQName;
|
||||
private final LinkedHashMap<String, String> myPseudoImports;
|
||||
private final DocumentReference[] myReferences;
|
||||
|
||||
public ImportClassUndoableAction(final String className,
|
||||
final String qName,
|
||||
final Document document,
|
||||
final LinkedHashMap<String, String> pseudoImportsMap) {
|
||||
super(document);
|
||||
myClassName = className;
|
||||
myQName = qName;
|
||||
myPseudoImports = pseudoImportsMap;
|
||||
myReferences = new DocumentReference[]{DocumentReferenceManager.getInstance().create(document)};
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void undo() {
|
||||
@@ -264,10 +257,6 @@ public class PsiCodeFragmentImpl extends PsiFileImpl implements JavaCodeFragment
|
||||
public void redo() {
|
||||
myPseudoImports.put(myClassName, myQName);
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return myReferences;
|
||||
}
|
||||
}
|
||||
|
||||
public ExceptionHandler getExceptionHandler() {
|
||||
|
||||
@@ -140,8 +140,9 @@ public abstract class WriteCommandAction<T> extends BaseActionRunnable<T> {
|
||||
// is put into undo queue
|
||||
final RunResult[] results = {result};
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
if (isGlobalUndoAction()) CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject);
|
||||
results[0].run();
|
||||
results[0] = null;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
*/
|
||||
package com.intellij.openapi.command.undo;
|
||||
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class UndoUtil {
|
||||
@@ -40,37 +40,13 @@ public class UndoUtil {
|
||||
Project project = file.getProject();
|
||||
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
if (document == null) return;
|
||||
final DocumentReference ref = DocumentReferenceManager.getInstance().create(document);
|
||||
markDocumentReferenceForUndo(project, ref, "markDocumentForUndo: " + file);
|
||||
CommandProcessor.getInstance().addAffectedDocuments(project, document);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated please use CommandProcessor.getInstance().addAffectedFiles instead
|
||||
*/
|
||||
public static void markVirtualFileForUndo(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
final DocumentReference ref = DocumentReferenceManager.getInstance().create(file);
|
||||
markDocumentReferenceForUndo(project, ref, "markVirtualFileForUndo: " + file.getPath());
|
||||
}
|
||||
|
||||
private static void markDocumentReferenceForUndo(final Project project,
|
||||
final DocumentReference ref,
|
||||
@NonNls final String debugName) {
|
||||
UndoManager.getInstance(project).undoableActionPerformed(new UndoableAction() {
|
||||
public void undo() {
|
||||
}
|
||||
|
||||
public void redo() {
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return new DocumentReference[]{ref};
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return debugName;
|
||||
}
|
||||
});
|
||||
CommandProcessor.getInstance().addAffectedFiles(project, file);
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,10 @@ import com.intellij.openapi.command.CommandAdapter;
|
||||
import com.intellij.openapi.command.CommandEvent;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.command.undo.BasicUndoableAction;
|
||||
import com.intellij.openapi.command.undo.DocumentReference;
|
||||
import com.intellij.openapi.command.undo.DocumentReferenceManager;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
@@ -246,10 +246,9 @@ public class TemplateState implements Disposable {
|
||||
|
||||
myProcessor = processor;
|
||||
|
||||
final DocumentReference[] refs =
|
||||
DocumentReference[] refs =
|
||||
myDocument == null ? null : new DocumentReference[]{DocumentReferenceManager.getInstance().create(myDocument)};
|
||||
|
||||
UndoManager.getInstance(myProject).undoableActionPerformed(new UndoableAction() {
|
||||
UndoManager.getInstance(myProject).undoableActionPerformed(new BasicUndoableAction(refs) {
|
||||
public void undo() {
|
||||
if (myDocument != null) {
|
||||
fireTemplateCancelled();
|
||||
@@ -264,14 +263,6 @@ public class TemplateState implements Disposable {
|
||||
//TODO:
|
||||
// throw new UnexpectedUndoException("Not implemented");
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return refs;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
myTemplateIndented = false;
|
||||
myCurrentVariableNumber = -1;
|
||||
|
||||
@@ -207,7 +207,7 @@ public class Browser extends JPanel {
|
||||
else if (ref.startsWith("invoke:")) {
|
||||
int actionNumber = Integer.parseInt(ref.substring("invoke:".length()));
|
||||
getTool().getQuickFixes(new RefElement[]{(RefElement)myCurrentEntity})[actionNumber]
|
||||
.doApplyFix(new RefElement[]{(RefElement)myCurrentEntity}, myView);
|
||||
.doApplyFix(new RefElement[]{(RefElement)myCurrentEntity}, myView, null);
|
||||
}
|
||||
else if (ref.startsWith("invokelocal:")) {
|
||||
int actionNumber = Integer.parseInt(ref.substring("invokelocal:".length()));
|
||||
|
||||
@@ -172,13 +172,12 @@ public class FileUndoProvider extends VirtualFileAdapter implements UndoProvider
|
||||
return (UndoManagerImpl)UndoManager.getGlobalInstance();
|
||||
}
|
||||
|
||||
private class MyUndoableAction implements UndoableAction {
|
||||
private final DocumentReference[] myReferences;
|
||||
private class MyUndoableAction extends GlobalUndoableAction {
|
||||
private ChangeRange myActionChangeRange;
|
||||
private ChangeRange myUndoChangeRange;
|
||||
|
||||
public MyUndoableAction(DocumentReference r) {
|
||||
myReferences = new DocumentReference[]{r};
|
||||
super(r);
|
||||
myActionChangeRange = new ChangeRange(myGateway, myLocalHistory, myLastChange);
|
||||
}
|
||||
|
||||
@@ -201,13 +200,5 @@ public class FileUndoProvider extends VirtualFileAdapter implements UndoProvider
|
||||
throw new UnexpectedUndoException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return myReferences;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class CommandProcessor {
|
||||
@@ -30,26 +31,37 @@ public abstract class CommandProcessor {
|
||||
/**
|
||||
* @deprecated use {@link #executeCommand(com.intellij.openapi.project.Project, java.lang.Runnable, java.lang.String, java.lang.Object)}
|
||||
*/
|
||||
public abstract void executeCommand(Runnable runnable, @Nls String name, Object groupId);
|
||||
public abstract void executeCommand(@NotNull Runnable runnable,
|
||||
@Nullable String name,
|
||||
@Nullable Object groupId);
|
||||
|
||||
public abstract void executeCommand(Project project, Runnable runnable, @Nls String name, Object groupId);
|
||||
public abstract void executeCommand(@Nullable Project project,
|
||||
@NotNull Runnable runnable,
|
||||
@Nullable String name,
|
||||
@Nullable Object groupId);
|
||||
|
||||
public abstract void executeCommand(Project project,
|
||||
Runnable runnable,
|
||||
@Nls String name,
|
||||
Object groupId,
|
||||
UndoConfirmationPolicy undoConfirmationPolicy);
|
||||
public abstract void executeCommand(@Nullable Project project,
|
||||
@NotNull Runnable runnable,
|
||||
@Nullable String name,
|
||||
@Nullable Object groupId,
|
||||
@Nullable Document document);
|
||||
|
||||
public abstract void executeCommand(Project project,
|
||||
Runnable command,
|
||||
String name,
|
||||
Object groupId,
|
||||
UndoConfirmationPolicy undoConfirmationPolicy,
|
||||
Document document);
|
||||
public abstract void executeCommand(@Nullable Project project,
|
||||
@NotNull Runnable runnable,
|
||||
@Nullable String name,
|
||||
@Nullable Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy);
|
||||
|
||||
public abstract void setCurrentCommandName(@Nls String name);
|
||||
public abstract void executeCommand(@Nullable Project project,
|
||||
@NotNull Runnable command,
|
||||
@Nullable String name,
|
||||
@Nullable Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy,
|
||||
@Nullable Document document);
|
||||
|
||||
public abstract void setCurrentCommandGroupId(Object groupId);
|
||||
public abstract void setCurrentCommandName(@Nullable String name);
|
||||
|
||||
public abstract void setCurrentCommandGroupId(@Nullable Object groupId);
|
||||
|
||||
@Nullable
|
||||
public abstract Runnable getCurrentCommand();
|
||||
@@ -63,15 +75,19 @@ public abstract class CommandProcessor {
|
||||
@Nullable
|
||||
public abstract Project getCurrentCommandProject();
|
||||
|
||||
public abstract void addCommandListener(CommandListener listener);
|
||||
|
||||
public abstract void addCommandListener(CommandListener listener, Disposable parentDisposable);
|
||||
|
||||
public abstract void removeCommandListener(CommandListener listener);
|
||||
|
||||
public abstract void runUndoTransparentAction(Runnable action);
|
||||
public abstract void runUndoTransparentAction(@NotNull Runnable action);
|
||||
|
||||
public abstract boolean isUndoTransparentActionInProgress();
|
||||
|
||||
public abstract void markCurrentCommandAsGlobal(Project project);
|
||||
public abstract void markCurrentCommandAsGlobal(@Nullable Project project);
|
||||
|
||||
public abstract void addAffectedDocuments(@Nullable Project project, @NotNull Document... docs);
|
||||
|
||||
public abstract void addAffectedFiles(@Nullable Project project, @NotNull VirtualFile... files);
|
||||
|
||||
public abstract void addCommandListener(@NotNull CommandListener listener);
|
||||
|
||||
public abstract void addCommandListener(@NotNull CommandListener listener, @NotNull Disposable parentDisposable);
|
||||
|
||||
public abstract void removeCommandListener(@NotNull CommandListener listener);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.openapi.command.undo;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class BasicUndoableAction implements UndoableAction {
|
||||
private final DocumentReference[] myRefs;
|
||||
|
||||
public BasicUndoableAction() {
|
||||
myRefs = null;
|
||||
}
|
||||
|
||||
public BasicUndoableAction(@Nullable DocumentReference... refs) {
|
||||
myRefs = refs;
|
||||
}
|
||||
|
||||
public BasicUndoableAction(@NotNull Document... docs) {
|
||||
myRefs = new DocumentReference[docs.length];
|
||||
for (int i = 0; i < docs.length; i++) {
|
||||
myRefs[i] = DocumentReferenceManager.getInstance().create(docs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public BasicUndoableAction(@NotNull VirtualFile... files) {
|
||||
myRefs = new DocumentReference[files.length];
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
myRefs[i] = DocumentReferenceManager.getInstance().create(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return myRefs;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+19
-7
@@ -16,15 +16,27 @@
|
||||
|
||||
package com.intellij.openapi.command.undo;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public abstract class NonDocumentUndoableAction implements UndoableAction {
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return null;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class GlobalUndoableAction extends BasicUndoableAction {
|
||||
public GlobalUndoableAction() {
|
||||
}
|
||||
|
||||
public final boolean isGlobal() {
|
||||
public GlobalUndoableAction(DocumentReference... refs) {
|
||||
super(refs);
|
||||
}
|
||||
|
||||
public GlobalUndoableAction(@NotNull Document... docs) {
|
||||
super(docs);
|
||||
}
|
||||
|
||||
public GlobalUndoableAction(@NotNull VirtualFile... files) {
|
||||
super(files);
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,6 @@ public interface UndoableAction {
|
||||
|
||||
/**
|
||||
* Global actions are those, that can be undone not only from the document of the file, but also from the project tree view.
|
||||
* */
|
||||
*/
|
||||
boolean isGlobal();
|
||||
}
|
||||
@@ -16,8 +16,10 @@
|
||||
package com.intellij.openapi.command.impl;
|
||||
|
||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.command.undo.BasicUndoableAction;
|
||||
import com.intellij.openapi.command.undo.DocumentReference;
|
||||
import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.command.undo.UnexpectedUndoException;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -37,7 +39,8 @@ public class CommandMerger {
|
||||
private String myCommandName = null;
|
||||
private boolean myValid = true;
|
||||
private List<UndoableAction> myCurrentActions = new ArrayList<UndoableAction>();
|
||||
private Set<DocumentReference> myAffectedDocuments = new THashSet<DocumentReference>();
|
||||
private Set<DocumentReference> myAllAffectedDocuments = new THashSet<DocumentReference>();
|
||||
private Set<DocumentReference> myAdditionalAffectedDocuments = new THashSet<DocumentReference>();
|
||||
private EditorAndState myStateBefore;
|
||||
private EditorAndState myStateAfter;
|
||||
private UndoConfirmationPolicy myUndoConfirmationPolicy = UndoConfirmationPolicy.DEFAULT;
|
||||
@@ -59,7 +62,7 @@ public class CommandMerger {
|
||||
myCurrentActions.add(action);
|
||||
DocumentReference[] refs = action.getAffectedDocuments();
|
||||
if (refs != null) {
|
||||
Collections.addAll(myAffectedDocuments, refs);
|
||||
Collections.addAll(myAllAffectedDocuments, refs);
|
||||
}
|
||||
myForcedGlobal |= action.isGlobal();
|
||||
}
|
||||
@@ -82,7 +85,7 @@ public class CommandMerger {
|
||||
|
||||
private boolean shouldMerge(Object groupId, CommandMerger nextCommandToMerge) {
|
||||
if (isTransparent() || nextCommandToMerge.isTransparent()) {
|
||||
return !hasActions() || !nextCommandToMerge.hasActions() || myAffectedDocuments.equals(nextCommandToMerge.myAffectedDocuments);
|
||||
return !hasActions() || !nextCommandToMerge.hasActions() || myAllAffectedDocuments.equals(nextCommandToMerge.myAllAffectedDocuments);
|
||||
}
|
||||
return !myForcedGlobal && !nextCommandToMerge.myForcedGlobal && canMergeGroup(groupId, myLastGroupId);
|
||||
}
|
||||
@@ -94,11 +97,12 @@ public class CommandMerger {
|
||||
private void merge(CommandMerger nextCommandToMerge) {
|
||||
setBeforeState(nextCommandToMerge.myStateBefore);
|
||||
myStateAfter = nextCommandToMerge.myStateAfter;
|
||||
if(myTransparent) { // todo write test
|
||||
if (myTransparent) { // todo write test
|
||||
if (nextCommandToMerge.hasActions()) {
|
||||
myTransparent &= nextCommandToMerge.myTransparent;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!hasActions()) {
|
||||
myTransparent = nextCommandToMerge.myTransparent;
|
||||
}
|
||||
@@ -106,7 +110,8 @@ public class CommandMerger {
|
||||
myValid &= nextCommandToMerge.myValid;
|
||||
myForcedGlobal |= nextCommandToMerge.myForcedGlobal;
|
||||
myCurrentActions.addAll(nextCommandToMerge.myCurrentActions);
|
||||
myAffectedDocuments.addAll(nextCommandToMerge.myAffectedDocuments);
|
||||
myAllAffectedDocuments.addAll(nextCommandToMerge.myAllAffectedDocuments);
|
||||
myAdditionalAffectedDocuments.addAll(nextCommandToMerge.myAdditionalAffectedDocuments);
|
||||
mergeUndoConfirmationPolicy(nextCommandToMerge.getUndoConfirmationPolicy());
|
||||
}
|
||||
|
||||
@@ -123,6 +128,19 @@ public class CommandMerger {
|
||||
|
||||
public void flushCurrentCommand() {
|
||||
if (hasActions()) {
|
||||
if (!myAdditionalAffectedDocuments.isEmpty()) {
|
||||
DocumentReference[] refs = myAdditionalAffectedDocuments.toArray(new DocumentReference[myAdditionalAffectedDocuments.size()]);
|
||||
myCurrentActions.add(new BasicUndoableAction(refs) {
|
||||
@Override
|
||||
public void undo() throws UnexpectedUndoException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redo() throws UnexpectedUndoException {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
myManager.getUndoStacksHolder().addToStacks(new UndoableGroup(myCommandName,
|
||||
isGlobal(),
|
||||
myManager.getProject(),
|
||||
@@ -140,7 +158,8 @@ public class CommandMerger {
|
||||
|
||||
private void reset() {
|
||||
myCurrentActions = new ArrayList<UndoableAction>();
|
||||
myAffectedDocuments = new THashSet<DocumentReference>();
|
||||
myAllAffectedDocuments = new THashSet<DocumentReference>();
|
||||
myAdditionalAffectedDocuments = new THashSet<DocumentReference>();
|
||||
myLastGroupId = null;
|
||||
myForcedGlobal = false;
|
||||
myTransparent = false;
|
||||
@@ -152,7 +171,7 @@ public class CommandMerger {
|
||||
}
|
||||
|
||||
private void clearRedoStacks(CommandMerger nextMerger) {
|
||||
myManager.getRedoStacksHolder().clearStacks(isGlobal(), nextMerger.myAffectedDocuments);
|
||||
myManager.getRedoStacksHolder().clearStacks(isGlobal(), nextMerger.myAllAffectedDocuments);
|
||||
}
|
||||
|
||||
boolean isGlobal() {
|
||||
@@ -169,7 +188,7 @@ public class CommandMerger {
|
||||
|
||||
private boolean affectsMultiplePhysicalDocs() {
|
||||
int count = 0;
|
||||
for (DocumentReference each : myAffectedDocuments) {
|
||||
for (DocumentReference each : myAllAffectedDocuments) {
|
||||
VirtualFile file = each.getFile();
|
||||
if (file instanceof LightVirtualFile) continue;
|
||||
if (++count > 1) return true;
|
||||
@@ -211,13 +230,10 @@ public class CommandMerger {
|
||||
return !myCurrentActions.isEmpty();
|
||||
}
|
||||
|
||||
public Collection<DocumentReference> getAffectedDocuments() {
|
||||
return myAffectedDocuments;
|
||||
}
|
||||
|
||||
public boolean isUndoAvailable(Collection<DocumentReference> refs) {
|
||||
if (hasNonUndoableActions()) return false;
|
||||
if (refs.isEmpty()) return isGlobal() && hasActions();
|
||||
|
||||
for (DocumentReference each : refs) {
|
||||
if (hasChangesOf(each)) return true;
|
||||
}
|
||||
@@ -236,7 +252,7 @@ public class CommandMerger {
|
||||
DocumentReference[] refs = action.getAffectedDocuments();
|
||||
if (refs == null || ArrayUtil.contains(ref, refs)) return true;
|
||||
}
|
||||
return false;
|
||||
return hasActions() && myAdditionalAffectedDocuments.contains(ref);
|
||||
}
|
||||
|
||||
public void setBeforeState(EditorAndState state) {
|
||||
@@ -249,8 +265,13 @@ public class CommandMerger {
|
||||
myStateAfter = state;
|
||||
}
|
||||
|
||||
public void addAdditionalAffectedDocuments(Collection<DocumentReference> refs) {
|
||||
myAllAffectedDocuments.addAll(refs);
|
||||
myAdditionalAffectedDocuments.addAll(refs);
|
||||
}
|
||||
|
||||
public void invalidateActionsFor(DocumentReference ref) {
|
||||
if (myAffectedDocuments.contains(ref)) {
|
||||
if (myAllAffectedDocuments.contains(ref)) {
|
||||
myValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-17
@@ -26,8 +26,10 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Stack;
|
||||
@@ -69,27 +71,31 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
|
||||
private int myUndoTransparentCount = 0;
|
||||
|
||||
public void executeCommand(Runnable runnable, String name, Object groupId) {
|
||||
public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) {
|
||||
executeCommand(null, runnable, name, groupId);
|
||||
}
|
||||
|
||||
public void executeCommand(Project project, Runnable runnable, String name, Object groupId) {
|
||||
public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) {
|
||||
executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
public void executeCommand(Project project,
|
||||
final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
UndoConfirmationPolicy undoConfirmationPolicy) {
|
||||
executeCommand(project, command, name, groupId, undoConfirmationPolicy, null);
|
||||
public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) {
|
||||
executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document);
|
||||
}
|
||||
|
||||
public void executeCommand(Project project,
|
||||
final Runnable command,
|
||||
@NotNull final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
UndoConfirmationPolicy undoConfirmationPolicy,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy) {
|
||||
executeCommand(project, command, name, groupId, confirmationPolicy, null);
|
||||
}
|
||||
|
||||
public void executeCommand(Project project,
|
||||
@NotNull final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy,
|
||||
Document document) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (project != null && project.isDisposed()) return;
|
||||
@@ -104,7 +110,7 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
}
|
||||
Throwable throwable = null;
|
||||
try {
|
||||
myCurrentCommand = new CommandDescriptor(command, project, name, groupId, undoConfirmationPolicy, document);
|
||||
myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document);
|
||||
fireCommandStarted();
|
||||
command.run();
|
||||
}
|
||||
@@ -263,11 +269,11 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
return myCurrentCommand != null ? myCurrentCommand.myProject : null;
|
||||
}
|
||||
|
||||
public void addCommandListener(CommandListener listener) {
|
||||
public void addCommandListener(@NotNull CommandListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
public void addCommandListener(final CommandListener listener, Disposable parentDisposable) {
|
||||
public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) {
|
||||
addCommandListener(listener);
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
public void dispose() {
|
||||
@@ -276,11 +282,11 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
});
|
||||
}
|
||||
|
||||
public void removeCommandListener(CommandListener listener) {
|
||||
public void removeCommandListener(@NotNull CommandListener listener) {
|
||||
myListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void runUndoTransparentAction(Runnable action) {
|
||||
public void runUndoTransparentAction(@NotNull Runnable action) {
|
||||
if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted();
|
||||
try {
|
||||
action.run();
|
||||
@@ -295,8 +301,21 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
}
|
||||
|
||||
public void markCurrentCommandAsGlobal(Project project) {
|
||||
UndoManager manager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance();
|
||||
((UndoManagerImpl)manager).markCurrentCommandAsGlobal();
|
||||
getUndoManager(project).markCurrentCommandAsGlobal();
|
||||
}
|
||||
|
||||
private UndoManagerImpl getUndoManager(Project project) {
|
||||
return (UndoManagerImpl)(project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAffectedDocuments(Project project, @NotNull Document... docs) {
|
||||
getUndoManager(project).addAffectedDocuments(docs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAffectedFiles(Project project, @NotNull VirtualFile... files) {
|
||||
getUndoManager(project).addAffectedFiles(files);
|
||||
}
|
||||
|
||||
private void fireCommandStarted() {
|
||||
|
||||
+5
-15
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.command.impl;
|
||||
|
||||
import com.intellij.openapi.command.undo.DocumentReference;
|
||||
import com.intellij.openapi.command.undo.DocumentReferenceManager;
|
||||
import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.command.undo.BasicUndoableAction;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
@@ -27,8 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
class EditorChangeAction implements UndoableAction {
|
||||
private final DocumentReference myReference;
|
||||
class EditorChangeAction extends BasicUndoableAction {
|
||||
private final int myOffset;
|
||||
private final CharSequence myOldString;
|
||||
private final CharSequence myNewString;
|
||||
@@ -41,7 +38,7 @@ class EditorChangeAction implements UndoableAction {
|
||||
CharSequence oldString,
|
||||
CharSequence newString,
|
||||
long oldTimeStamp) {
|
||||
myReference = DocumentReferenceManager.getInstance().create(document);
|
||||
super(document);
|
||||
|
||||
myOffset = offset;
|
||||
myOldString = oldString == null ? "" : oldString;
|
||||
@@ -83,7 +80,7 @@ class EditorChangeAction implements UndoableAction {
|
||||
}
|
||||
|
||||
private void refreshFileStatus() {
|
||||
VirtualFile f = myReference.getFile();
|
||||
VirtualFile f = getAffectedDocuments()[0].getFile();
|
||||
if (f == null || f instanceof LightVirtualFile) return;
|
||||
|
||||
for (Project each : ProjectManager.getInstance().getOpenProjects()) {
|
||||
@@ -92,16 +89,9 @@ class EditorChangeAction implements UndoableAction {
|
||||
}
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return new DocumentReference[]{myReference};
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private DocumentEx getDocument() {
|
||||
return (DocumentEx)myReference.getDocument();
|
||||
return (DocumentEx)getAffectedDocuments()[0].getDocument();
|
||||
}
|
||||
|
||||
@NonNls
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.command.undo.UnexpectedUndoException;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
|
||||
public class NonUndoableAction implements UndoableAction {
|
||||
class NonUndoableAction implements UndoableAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.undo.NonUndoableAction");
|
||||
|
||||
private final DocumentReference[] myRefs;
|
||||
|
||||
@@ -155,6 +155,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
|
||||
|
||||
public void commandStarted(CommandEvent event) {
|
||||
onCommandStarted(event.getProject(), event.getUndoConfirmationPolicy());
|
||||
if (event.getDocument() != null) addAffectedDocuments(event.getDocument());
|
||||
}
|
||||
|
||||
public void commandFinished(CommandEvent event) {
|
||||
@@ -257,10 +258,6 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
|
||||
}
|
||||
}
|
||||
|
||||
public void markCurrentCommandAsGlobal() {
|
||||
myCurrentMerger.markAsGlobal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nonundoableActionPerformed(final DocumentReference ref, final boolean isGlobal) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
@@ -284,6 +281,34 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
|
||||
myCurrentMerger.addAction(action);
|
||||
}
|
||||
|
||||
public void markCurrentCommandAsGlobal() {
|
||||
myCurrentMerger.markAsGlobal();
|
||||
}
|
||||
|
||||
public void addAffectedDocuments(Document... docs) {
|
||||
if (!isInsideCommand()) {
|
||||
LOG.error("Must be called inside command");
|
||||
return;
|
||||
}
|
||||
List<DocumentReference> refs = new ArrayList<DocumentReference>(docs.length);
|
||||
for (Document each : docs) {
|
||||
refs.add(DocumentReferenceManager.getInstance().create(each));
|
||||
}
|
||||
myCurrentMerger.addAdditionalAffectedDocuments(refs);
|
||||
}
|
||||
|
||||
public void addAffectedFiles(VirtualFile... files) {
|
||||
if (!isInsideCommand()) {
|
||||
LOG.error("Must be called inside command");
|
||||
return;
|
||||
}
|
||||
List<DocumentReference> refs = new ArrayList<DocumentReference>(files.length);
|
||||
for (VirtualFile each : files) {
|
||||
refs.add(DocumentReferenceManager.getInstance().create(each));
|
||||
}
|
||||
myCurrentMerger.addAdditionalAffectedDocuments(refs);
|
||||
}
|
||||
|
||||
public void invalidateActionsFor(DocumentReference ref) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
myMerger.invalidateActionsFor(ref);
|
||||
|
||||
@@ -22,10 +22,13 @@ import com.intellij.ide.plugins.cl.PluginClassLoader;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.command.undo.DocumentReference;
|
||||
import com.intellij.openapi.command.undo.GlobalUndoableAction;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.command.undo.UndoableAction;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -59,7 +62,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Configuration that holds configured xml tag, attribute and method parameter
|
||||
@@ -529,7 +531,7 @@ public final class Configuration implements PersistentStateComponent<Element>, M
|
||||
public static <T> void replaceInjectionsWithUndo(final Project project, final T add, final T remove,
|
||||
final List<? extends PsiElement> psiElementsToRemove,
|
||||
final PairProcessor<T, T> actualProcessor) {
|
||||
final UndoableAction action = new UndoableAction() {
|
||||
final UndoableAction action = new GlobalUndoableAction() {
|
||||
public void undo() {
|
||||
actualProcessor.process(remove, add);
|
||||
}
|
||||
@@ -537,14 +539,6 @@ public final class Configuration implements PersistentStateComponent<Element>, M
|
||||
public void redo() {
|
||||
actualProcessor.process(add, remove);
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return DocumentReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final List<PsiFile> psiFiles = ContainerUtil.mapNotNull(psiElementsToRemove, new NullableFunction<PsiElement, PsiFile>() {
|
||||
public PsiFile fun(final PsiElement psiAnnotation) {
|
||||
|
||||
+5
-12
@@ -17,7 +17,9 @@ package org.jetbrains.plugins.groovy.annotator.intentions.dynamic.ui;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.undo.*;
|
||||
import com.intellij.openapi.command.undo.GlobalUndoableAction;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.command.undo.UnexpectedUndoException;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
@@ -330,12 +332,11 @@ public abstract class DynamicDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
Document document = PsiDocumentManager.getInstance(myProject).getDocument(myContext.getContainingFile());
|
||||
final DocumentReference[] refs = new DocumentReference[]{DocumentReferenceManager.getInstance().create(document)};
|
||||
final Document document = PsiDocumentManager.getInstance(myProject).getDocument(myContext.getContainingFile());
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
UndoManager.getInstance(myProject).undoableActionPerformed(new UndoableAction() {
|
||||
UndoManager.getInstance(myProject).undoableActionPerformed(new GlobalUndoableAction(document) {
|
||||
public void undo() throws UnexpectedUndoException {
|
||||
|
||||
final DItemElement itemElement;
|
||||
@@ -368,14 +369,6 @@ public abstract class DynamicDialog extends DialogWrapper {
|
||||
public void redo() throws UnexpectedUndoException {
|
||||
addElement(mySettings);
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
return refs;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
addElement(mySettings);
|
||||
|
||||
Reference in New Issue
Block a user