diff options
Diffstat (limited to 'bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/undo/StructuredTextUndoManager.java')
-rw-r--r-- | bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/undo/StructuredTextUndoManager.java | 652 |
1 files changed, 0 insertions, 652 deletions
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/undo/StructuredTextUndoManager.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/undo/StructuredTextUndoManager.java deleted file mode 100644 index ebd028070b..0000000000 --- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/undo/StructuredTextUndoManager.java +++ /dev/null @@ -1,652 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2001, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Jens Lukowski/Innoopract - initial renaming/restructuring - * Jesper Steen Møller - initial IDocumentExtension4 support - #102822 - * - *******************************************************************************/ -package org.eclipse.wst.sse.core.internal.undo; - -import java.util.EventObject; - -import org.eclipse.emf.common.command.BasicCommandStack; -import org.eclipse.emf.common.command.Command; -import org.eclipse.emf.common.command.CommandStack; -import org.eclipse.emf.common.command.CommandStackListener; -import org.eclipse.emf.common.command.CompoundCommand; -import org.eclipse.jface.text.DocumentRewriteSession; -import org.eclipse.jface.text.DocumentRewriteSessionType; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentExtension4; -import org.eclipse.wst.sse.core.StructuredModelManager; -import org.eclipse.wst.sse.core.internal.SSECoreMessages; -import org.eclipse.wst.sse.core.internal.provisional.IModelManager; -import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; -import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener; -import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent; -import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent; -import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent; -import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent; -import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent; -import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; -import org.eclipse.wst.sse.core.internal.util.Assert; -import org.eclipse.wst.sse.core.internal.util.Utilities; - -public class StructuredTextUndoManager implements IStructuredTextUndoManager { - - class InternalCommandStackListener implements CommandStackListener { - public void commandStackChanged(EventObject event) { - resetInternalCommands(); - } - } - - class InternalStructuredDocumentListener implements IStructuredDocumentListener { - - public void newModel(NewDocumentEvent structuredDocumentEvent) { - // Do nothing. Do not push the new model's structuredDocument - // changes - // onto the undo command stack, or else the user may be able to - // undo - // an existing file to an empty file. - } - - public void noChange(NoChangeEvent structuredDocumentEvent) { - // Since "no change", do nothing. - } - - public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) { - processStructuredDocumentEvent(structuredDocumentEvent); - } - - private void processStructuredDocumentEvent(String textDeleted, String textInserted, int textStart, int textEnd) { - if (fTextCommand != null && textStart == fTextCommand.getTextEnd()) { - // append to the text command - fTextCommand.setTextDeleted(fTextCommand.getTextDeleted().concat(textDeleted)); - fTextCommand.setTextInserted(fTextCommand.getTextInserted().concat(textInserted)); - fTextCommand.setTextEnd(textEnd); - } - else if (fTextCommand != null && textStart == fTextCommand.getTextStart() - (textEnd - textStart + 1) && textEnd <= fTextCommand.getTextEnd() - (textEnd - textStart + 1) && textDeleted.length() == 1 && textInserted.length() == 0) { - // backspace pressed - - // erase a character just inserted - if (fTextCommand.getTextInserted().length() > 0) { - fTextCommand.setTextInserted(fTextCommand.getTextInserted().substring(0, fTextCommand.getTextEnd() - fTextCommand.getTextStart() - 1)); - fTextCommand.setTextEnd(textEnd); - } - // erase a character in the file - else { - fTextCommand.setTextDeleted(textDeleted.concat(fTextCommand.getTextDeleted())); - fTextCommand.setTextStart(textStart); - } - } - else { - createNewTextCommand(textDeleted, textInserted, textStart, textEnd); - } - - // save cursor position - fCursorPosition = textEnd; - } - - private void processStructuredDocumentEvent(StructuredDocumentEvent structuredDocumentEvent) { - // Note: fListening tells us if we should listen to the - // StructuredDocumentEvent. - // fListening is set to false right before the undo/redo process - // and - // then set to true again - // right after the undo/redo process to block out and ignore all - // StructuredDocumentEvents generated - // by the undo/redo process. - - // Process StructuredDocumentEvent if fListening is true. - // - // We are executing a command from the command stack if the - // requester - // is a command (for example, undo/redo). - // We should not process the flat model event when we are - // executing a - // command from the command stack. - if (fUndoManagementEnabled && !(structuredDocumentEvent.getOriginalRequester() instanceof Command)) { - // check requester if not recording - if (!fRecording) - checkRequester(structuredDocumentEvent.getOriginalRequester()); - - // process the structuredDocumentEvent - String textDeleted = structuredDocumentEvent.getDeletedText(); - String textInserted = structuredDocumentEvent.getText(); - int textStart = structuredDocumentEvent.getOffset(); - int textEnd = textStart + textInserted.length(); - processStructuredDocumentEvent(textDeleted, textInserted, textStart, textEnd); - } - } - - public void regionChanged(RegionChangedEvent structuredDocumentEvent) { - processStructuredDocumentEvent(structuredDocumentEvent); - } - - public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) { - processStructuredDocumentEvent(structuredDocumentEvent); - } - - } - - private static final String TEXT_CHANGE_TEXT = SSECoreMessages.Text_Change_UI_; //$NON-NLS-1$ - private CommandStack fCommandStack = null; - private StructuredTextCompoundCommandImpl fCompoundCommand = null; - private String fCompoundCommandDescription = null; - private String fCompoundCommandLabel = null; - int fCursorPosition = 0; - // private IStructuredModel fStructuredModel = null; - private IDocument fDocument; - private InternalCommandStackListener fInternalCommandStackListener; - // private Map fTextViewerToListenerMap = new HashMap(); - private IStructuredDocumentListener fInternalStructuredDocumentListener; - private IDocumentSelectionMediator[] fMediators = null; - private boolean fRecording = false; - private int fRecordingCount = 0; - private Object fRequester; - StructuredTextCommandImpl fTextCommand = null; - private int fUndoCursorPosition = -1; - boolean fUndoManagementEnabled = true; - private int fUndoSelectionLength = 0; - - public StructuredTextUndoManager() { - this(new BasicCommandStack()); - } - - public StructuredTextUndoManager(CommandStack commandStack) { - setCommandStack(commandStack); - } - - private void addDocumentSelectionMediator(IDocumentSelectionMediator mediator) { - if (!Utilities.contains(fMediators, mediator)) { - int oldSize = 0; - - if (fMediators != null) { - // normally won't be null, but we need to be sure, for first - // time through - oldSize = fMediators.length; - } - - int newSize = oldSize + 1; - IDocumentSelectionMediator[] newMediators = new IDocumentSelectionMediator[newSize]; - if (fMediators != null) { - System.arraycopy(fMediators, 0, newMediators, 0, oldSize); - } - - // add the new undo mediator to last position - newMediators[newSize - 1] = mediator; - - // now switch new for old - fMediators = newMediators; - } - else { - removeDocumentSelectionMediator(mediator); - addDocumentSelectionMediator(mediator); - } - } - - public void beginRecording(Object requester) { - beginRecording(requester, null, null); - } - - public void beginRecording(Object requester, int cursorPosition, int selectionLength) { - beginRecording(requester, null, null); - - fUndoCursorPosition = cursorPosition; - fUndoSelectionLength = selectionLength; - } - - public void beginRecording(Object requester, String label) { - beginRecording(requester, label, null); - } - - public void beginRecording(Object requester, String label, int cursorPosition, int selectionLength) { - beginRecording(requester, label, null); - - fUndoCursorPosition = cursorPosition; - fUndoSelectionLength = selectionLength; - } - - public void beginRecording(Object requester, String label, String description) { - // save the requester - fRequester = requester; - - // update label and desc only on the first level when recording is - // nested - if (fRecordingCount == 0) { - fCompoundCommandLabel = label; - if (fCompoundCommandLabel == null) - fCompoundCommandLabel = TEXT_CHANGE_TEXT; - - fCompoundCommandDescription = description; - if (fCompoundCommandDescription == null) - fCompoundCommandDescription = TEXT_CHANGE_TEXT; - - // clear commands - fTextCommand = null; - fCompoundCommand = null; - } - - // update counter and flag - fRecordingCount++; - fRecording = true; - - // no undo cursor position and undo selection length specified - // reset undo cursor position and undo selection length - fUndoCursorPosition = -1; - fUndoSelectionLength = 0; - } - - public void beginRecording(Object requester, String label, String description, int cursorPosition, int selectionLength) { - beginRecording(requester, label, description); - - fUndoCursorPosition = cursorPosition; - fUndoSelectionLength = selectionLength; - } - - void checkRequester(Object requester) { - if (fRequester != null && !fRequester.equals(requester)) { - // Force restart of recording so the last compound command is - // closed. - // - // However, we should not force restart of recording when the - // request came from StructuredDocumentToTextAdapter or - // XMLModelImpl - // because cut/paste requests and character inserts to the - // textViewer are from StructuredDocumentToTextAdapter, - // and requests to delete a node in the XMLTableTreeViewer are - // from XMLModelImpl (which implements IStructuredModel). - - if (!(requester instanceof IStructuredModel || requester instanceof IStructuredDocument)) { - resetInternalCommands(); - } - } - } - - - - public void connect(IDocumentSelectionMediator mediator) { - Assert.isNotNull(mediator); - if (fDocument == null) { - // add this undo manager as structured document listener - fDocument = mediator.getDocument(); - // future_TODO: eventually we want to refactor or allow either - // type of document, but for now, we'll do instanceof check, and - // fail - // if not right type - if (fDocument instanceof IStructuredDocument) { - ((IStructuredDocument) fDocument).addDocumentChangedListener(getInternalStructuredDocumentListener()); - } - else { - throw new IllegalArgumentException("only meditator with structured documents currently handled"); //$NON-NLS-1$ - } - } - else { - // if we've already had our document set, we'll just do this fail - // fast integrity check - if (!fDocument.equals(mediator.getDocument())) - throw new IllegalStateException("Connection to undo manager failed. Document for document selection mediator inconistent with undo manager."); //$NON-NLS-1$ - } - - addDocumentSelectionMediator(mediator); - } - - void createNewTextCommand(String textDeleted, String textInserted, int textStart, int textEnd) { - StructuredTextCommandImpl textCommand = new StructuredTextCommandImpl(fDocument); - textCommand.setLabel(TEXT_CHANGE_TEXT); - textCommand.setDescription(TEXT_CHANGE_TEXT); - textCommand.setTextStart(textStart); - textCommand.setTextEnd(textEnd); - textCommand.setTextDeleted(textDeleted); - textCommand.setTextInserted(textInserted); - - if (fRecording) { - if (fCompoundCommand == null) { - StructuredTextCompoundCommandImpl compoundCommand = new StructuredTextCompoundCommandImpl(); - compoundCommand.setUndoCursorPosition(fUndoCursorPosition); - compoundCommand.setUndoSelectionLength(fUndoSelectionLength); - - compoundCommand.setLabel(fCompoundCommandLabel); - compoundCommand.setDescription(fCompoundCommandDescription); - compoundCommand.append(textCommand); - fCommandStack.execute(compoundCommand); - - fCompoundCommand = compoundCommand; - } - else { - fCompoundCommand.append(textCommand); - } - } - else { - fCommandStack.execute(textCommand); - } - - fTextCommand = textCommand; - } - - /** - * Disable undo management. - */ - public void disableUndoManagement() { - fUndoManagementEnabled = false; - } - - public void disconnect(IDocumentSelectionMediator mediator) { - removeDocumentSelectionMediator(mediator); - - if (fMediators != null && fMediators.length == 0 && fDocument != null) { - // remove this undo manager as structured document listener - // future_TODO: eventually we want to refactor or allow either - // type of document, but for now, we'll do instanceof check, and - // fail - // if not right type - if (fDocument instanceof IStructuredDocument) { - ((IStructuredDocument) fDocument).removeDocumentChangedListener(getInternalStructuredDocumentListener()); - } - else { - throw new IllegalArgumentException("only meditator with structured documents currently handled"); //$NON-NLS-1$ - } - // if no longer listening to document, then dont even track it - // anymore - // (this allows connect to reconnect to document again) - fDocument = null; - } - } - - public void enableUndoManagement() { - fUndoManagementEnabled = true; - } - - public void endRecording(Object requester) { - int cursorPosition = (fTextCommand != null) ? fTextCommand.getTextEnd() : -1; - int selectionLength = 0; - - endRecording(requester, cursorPosition, selectionLength); - } - - public void endRecording(Object requester, int cursorPosition, int selectionLength) { - // Recording could be stopped by forceEndOfPendingCommand(). Make sure - // we are still recording before proceeding, or else fRecordingCount - // may not be balanced. - if (fRecording) { - if (fCompoundCommand != null) { - fCompoundCommand.setRedoCursorPosition(cursorPosition); - fCompoundCommand.setRedoSelectionLength(selectionLength); - } - - // end recording is a logical stopping point for text command, - // even when fRecordingCount > 0 (in nested beginRecording) - fTextCommand = null; - - // update counter and flag - if (fRecordingCount > 0) - fRecordingCount--; - if (fRecordingCount == 0) { - fRecording = false; - - // reset compound command only when fRecordingCount == - // 0 - fCompoundCommand = null; - fCompoundCommandLabel = null; - fCompoundCommandDescription = null; - - // Also reset fRequester - fRequester = null; - } - } - } - - /** - * Utility method to find model given document - */ - private IStructuredModel findStructuredModel(IDocument document) { - IModelManager modelManager = StructuredModelManager.getModelManager(); - IStructuredModel structuredModel = modelManager.getExistingModelForRead(document); - return structuredModel; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager#forceEndOfPendingCommand(java.lang.Object, - * int, int) - */ - public void forceEndOfPendingCommand(Object requester, int currentPosition, int length) { - if (fRecording) - endRecording(requester, currentPosition, length); - else - resetInternalCommands(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager#getCommandStack() - */ - public CommandStack getCommandStack() { - return fCommandStack; - } - - /** - * @return - */ - private CommandStackListener getInternalCommandStackListener() { - if (fInternalCommandStackListener == null) { - fInternalCommandStackListener = new InternalCommandStackListener(); - } - return fInternalCommandStackListener; - } - - /** - * @return - */ - private IStructuredDocumentListener getInternalStructuredDocumentListener() { - if (fInternalStructuredDocumentListener == null) { - fInternalStructuredDocumentListener = new InternalStructuredDocumentListener(); - } - return fInternalStructuredDocumentListener; - } - - public Command getRedoCommand() { - return fCommandStack.getRedoCommand(); - } - - public Command getUndoCommand() { - return fCommandStack.getUndoCommand(); - } - - public void redo() { - redo(null); - } - - public void redo(IDocumentSelectionMediator requester) { - IStructuredModel model = findStructuredModel(fDocument); - - if (redoable()) { - IDocumentExtension4 docExt4 = null; - DocumentRewriteSession rewriteSession = null; - try { - if (model != null) - model.aboutToChangeModel(); - - Command redoCommand = getRedoCommand(); - if (redoCommand instanceof CompoundCommand && - model.getStructuredDocument() instanceof IDocumentExtension4) { - docExt4 = (IDocumentExtension4)model.getStructuredDocument(); - } - rewriteSession = (docExt4 == null) ? null : - docExt4.startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED); - - // make sure to redo before setting document selection - fCommandStack.redo(); - - // set document selection - setRedoDocumentSelection(requester, redoCommand); - } - finally { - if (docExt4 != null && rewriteSession != null) - docExt4.stopRewriteSession(rewriteSession); - if (model != null) { - model.changedModel(); - model.releaseFromRead(); - } - } - } - } - - public boolean redoable() { - return fCommandStack.canRedo(); - } - - private void removeDocumentSelectionMediator(IDocumentSelectionMediator mediator) { - if (fMediators != null && mediator != null) { - // if its not in the array, we'll ignore the request - if (Utilities.contains(fMediators, mediator)) { - int oldSize = fMediators.length; - int newSize = oldSize - 1; - IDocumentSelectionMediator[] newMediators = new IDocumentSelectionMediator[newSize]; - int index = 0; - for (int i = 0; i < oldSize; i++) { - if (fMediators[i] == mediator) { // ignore - } - else { - // copy old to new if its not the one we are removing - newMediators[index++] = fMediators[i]; - } - } - // now that we have a new array, let's switch it for the old - // one - fMediators = newMediators; - } - } - } - - void resetInternalCommands() { - // Either the requester of the structured document change event is - // changed, or the command stack is changed. Need to reset internal - // commands so we won't continue to append changes. - fCompoundCommand = null; - fTextCommand = null; - - // Also reset fRequester - fRequester = null; - } - - public void setCommandStack(CommandStack commandStack) { - if (fCommandStack != null) - fCommandStack.removeCommandStackListener(getInternalCommandStackListener()); - - fCommandStack = commandStack; - - if (fCommandStack != null) - fCommandStack.addCommandStackListener(getInternalCommandStackListener()); - } - - private void setRedoDocumentSelection(IDocumentSelectionMediator requester, Command command) { - int cursorPosition = -1; - int selectionLength = 0; - - if (command instanceof CommandCursorPosition) { - CommandCursorPosition commandCursorPosition = (CommandCursorPosition) command; - cursorPosition = commandCursorPosition.getRedoCursorPosition(); - selectionLength = commandCursorPosition.getRedoSelectionLength(); - } - else if (command instanceof StructuredTextCommand) { - StructuredTextCommand structuredTextCommand = (StructuredTextCommand) command; - cursorPosition = structuredTextCommand.getTextStart(); - selectionLength = structuredTextCommand.getTextInserted().length(); - } - - if (cursorPosition > -1 && fMediators != null && fMediators.length > 0) { - for (int i = 0; i < fMediators.length; i++) { - IDocument document = fMediators[i].getDocument(); - fMediators[i].undoOperationSelectionChanged(new UndoDocumentEvent(requester, document, cursorPosition, selectionLength)); - } - } - } - - private void setUndoDocumentSelection(IDocumentSelectionMediator requester, Command command) { - int cursorPosition = -1; - int selectionLength = 0; - - if (command instanceof CommandCursorPosition) { - CommandCursorPosition commandCursorPosition = (CommandCursorPosition) command; - cursorPosition = commandCursorPosition.getUndoCursorPosition(); - selectionLength = commandCursorPosition.getUndoSelectionLength(); - } - else if (command instanceof StructuredTextCommand) { - StructuredTextCommand structuredTextCommand = (StructuredTextCommand) command; - cursorPosition = structuredTextCommand.getTextStart(); - selectionLength = structuredTextCommand.getTextDeleted().length(); - } - - if (cursorPosition > -1 && fMediators != null && fMediators.length > 0) { - for (int i = 0; i < fMediators.length; i++) { - IDocument document = fMediators[i].getDocument(); - fMediators[i].undoOperationSelectionChanged(new UndoDocumentEvent(requester, document, cursorPosition, selectionLength)); - } - } - } - - public void undo() { - undo(null); - } - - public void undo(IDocumentSelectionMediator requester) { - // Force an endRecording before undo. - // - // For example, recording was turned on on the Design Page of - // PageDesigner. - // Then undo is invoked on the Source Page. Recording should be - // stopped before we undo. - // Note that redo should not be available when we switch to the Source - // Page. - // Therefore, this force ending of recording is not needed in redo. - if (fRecording) - endRecording(this); - - if (undoable()) { - IStructuredModel model = findStructuredModel(fDocument); - IDocumentExtension4 docExt4 = null; - DocumentRewriteSession rewriteSession = null; - - try { - if (model != null) - model.aboutToChangeModel(); - - Command undoCommand = getUndoCommand(); - if (undoCommand instanceof CompoundCommand && - model.getStructuredDocument() instanceof IDocumentExtension4) { - docExt4 = (IDocumentExtension4)model.getStructuredDocument(); - } - rewriteSession = (docExt4 == null) ? null : - docExt4.startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED); - - // make sure to undo before setting document selection - fCommandStack.undo(); - - // set document selection - setUndoDocumentSelection(requester, undoCommand); - } - finally { - if (docExt4 != null && rewriteSession != null) - docExt4.stopRewriteSession(rewriteSession); - if (model != null) { - model.changedModel(); - model.releaseFromRead(); - } - } - } - } - - public boolean undoable() { - return fCommandStack.canUndo(); - } -} |