mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
perform massive undo in one big bulkmode
This commit is contained in:
@@ -31,7 +31,6 @@ class EditorChangeAction extends BasicUndoableAction {
|
||||
private final CharSequence myNewString;
|
||||
private final long myOldTimeStamp;
|
||||
private final long myNewTimeStamp;
|
||||
private final boolean myBulkUpdate;
|
||||
|
||||
public EditorChangeAction(DocumentEx document,
|
||||
int offset,
|
||||
@@ -45,8 +44,6 @@ class EditorChangeAction extends BasicUndoableAction {
|
||||
myNewString = newString == null ? "" : newString;
|
||||
myOldTimeStamp = oldTimeStamp;
|
||||
myNewTimeStamp = document.getModificationStamp();
|
||||
|
||||
myBulkUpdate = document.isInBulkUpdate();
|
||||
}
|
||||
|
||||
public void undo() {
|
||||
@@ -64,8 +61,6 @@ class EditorChangeAction extends BasicUndoableAction {
|
||||
private void exchangeStrings(CharSequence newString, CharSequence oldString) {
|
||||
DocumentEx d = getDocument();
|
||||
|
||||
if (myBulkUpdate) d.setInBulkUpdate(true);
|
||||
|
||||
if (newString.length() > 0 && oldString.length() == 0) {
|
||||
d.deleteString(myOffset, myOffset + newString.length());
|
||||
}
|
||||
@@ -75,8 +70,6 @@ class EditorChangeAction extends BasicUndoableAction {
|
||||
else if (oldString.length() > 0 && newString.length() > 0) {
|
||||
d.replaceString(myOffset, myOffset + newString.length(), oldString);
|
||||
}
|
||||
|
||||
if (myBulkUpdate) d.setInBulkUpdate(false);
|
||||
}
|
||||
|
||||
private void refreshFileStatus() {
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.openapi.command.impl;
|
||||
|
||||
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.diagnostic.Logger;
|
||||
|
||||
class NonUndoableAction implements UndoableAction {
|
||||
@@ -31,12 +30,12 @@ class NonUndoableAction implements UndoableAction {
|
||||
myRefs = new DocumentReference[]{ref};
|
||||
}
|
||||
|
||||
public final void undo() throws UnexpectedUndoException {
|
||||
LOG.assertTrue(false);
|
||||
public final void undo() {
|
||||
LOG.error("Cannot undo");
|
||||
}
|
||||
|
||||
public void redo() throws UnexpectedUndoException {
|
||||
LOG.assertTrue(false);
|
||||
public void redo() {
|
||||
LOG.error("Cannot redo");
|
||||
}
|
||||
|
||||
public DocumentReference[] getAffectedDocuments() {
|
||||
@@ -46,4 +45,4 @@ class NonUndoableAction implements UndoableAction {
|
||||
public boolean isGlobal() {
|
||||
return myGlobal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ 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.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -32,11 +33,9 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
class UndoableGroup {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.impl.UndoableGroup");
|
||||
@@ -99,19 +98,13 @@ class UndoableGroup {
|
||||
}
|
||||
|
||||
private void undoOrRedo(boolean isUndo) {
|
||||
LocalHistoryAction action = LocalHistoryAction.NULL;
|
||||
|
||||
if (myProject != null) {
|
||||
if (isGlobal()) {
|
||||
final String actionName;
|
||||
if (isUndo) {
|
||||
actionName = CommonBundle.message("local.vcs.action.name.undo.command", myCommandName);
|
||||
}
|
||||
else {
|
||||
actionName = CommonBundle.message("local.vcs.action.name.redo.command", myCommandName);
|
||||
}
|
||||
action = LocalHistory.getInstance().startAction(actionName);
|
||||
}
|
||||
LocalHistoryAction action;
|
||||
if (myProject != null && isGlobal()) {
|
||||
String actionName = CommonBundle.message(isUndo ? "local.vcs.action.name.undo.command" : "local.vcs.action.name.redo.command", myCommandName);
|
||||
action = LocalHistory.getInstance().startAction(actionName);
|
||||
}
|
||||
else {
|
||||
action = LocalHistoryAction.NULL;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -122,8 +115,35 @@ class UndoableGroup {
|
||||
}
|
||||
}
|
||||
|
||||
private static void doInBulkMode(@NotNull final Runnable action, @NotNull Collection<DocumentEx> documents) {
|
||||
Runnable runnable = action;
|
||||
for (final DocumentEx document : documents) {
|
||||
final Runnable oldRunnable = runnable;
|
||||
runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInBulkMode(oldRunnable, document);
|
||||
}
|
||||
};
|
||||
}
|
||||
runnable.run();
|
||||
}
|
||||
private static void doInBulkMode(@NotNull Runnable action, @NotNull DocumentEx document) {
|
||||
boolean wasInBulkUpdate = document.isInBulkUpdate();
|
||||
document.setInBulkUpdate(true);
|
||||
try {
|
||||
action.run();
|
||||
}
|
||||
finally {
|
||||
if (!wasInBulkUpdate) {
|
||||
document.setInBulkUpdate(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void doUndoOrRedo(final boolean isUndo) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
for (UndoableAction each : isUndo ? ContainerUtil.iterateBackward(myActions) : myActions) {
|
||||
@@ -139,7 +159,27 @@ class UndoableGroup {
|
||||
reportUndoProblem(e, isUndo);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
if (myActions.size() > 50) {
|
||||
final Collection<DocumentEx> documents = new THashSet<DocumentEx>();
|
||||
for (UndoableAction action : myActions) {
|
||||
DocumentReference[] affectedDocuments = action.getAffectedDocuments();
|
||||
if (affectedDocuments != null) {
|
||||
for (DocumentReference affectedDocument : affectedDocuments) {
|
||||
documents.add((DocumentEx)affectedDocument.getDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
final Runnable oldRunnable = runnable;
|
||||
runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInBulkMode(oldRunnable, documents);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
commitAllDocuments();
|
||||
}
|
||||
|
||||
@@ -207,9 +247,8 @@ class UndoableGroup {
|
||||
}
|
||||
|
||||
public boolean shouldAskConfirmation() {
|
||||
if (myConfirmationPolicy == UndoConfirmationPolicy.REQUEST_CONFIRMATION) return true;
|
||||
if (myConfirmationPolicy == UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION) return false;
|
||||
return myGlobal;
|
||||
return myConfirmationPolicy == UndoConfirmationPolicy.REQUEST_CONFIRMATION ||
|
||||
myConfirmationPolicy != UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION && myGlobal;
|
||||
}
|
||||
|
||||
public void invalidateActionsFor(DocumentReference ref) {
|
||||
|
||||
Reference in New Issue
Block a user