001: /*
002: * UndoLineEdit.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: UndoLineEdit.java,v 1.3 2003/06/11 13:54:39 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import javax.swing.undo.AbstractUndoableEdit;
025: import javax.swing.undo.UndoableEdit;
026:
027: public class UndoLineEdit extends AbstractUndoableEdit implements
028: Constants, UndoableEdit {
029: private final Buffer buffer;
030: private final int changeLineNumber;
031: private final State preState;
032: private State postState;
033:
034: public UndoLineEdit(Editor editor) {
035: buffer = editor.getBuffer();
036: changeLineNumber = editor.getDot().lineNumber();
037: preState = new State(editor);
038: }
039:
040: public UndoLineEdit(Buffer buffer, Line line) {
041: this .buffer = buffer;
042: changeLineNumber = line.lineNumber();
043: preState = new State(buffer);
044: }
045:
046: public boolean addEdit(UndoableEdit edit) {
047: if (edit instanceof UndoLineEdit) {
048: UndoLineEdit e = (UndoLineEdit) edit;
049: if (e.changeLineNumber == this .changeLineNumber)
050: return true;
051: }
052: return false;
053: }
054:
055: public void undo() {
056: super .undo();
057: final Editor editor = Editor.currentEditor();
058: Debug.assertTrue(editor.getBuffer() == buffer);
059: postState = new State(editor);
060: preState.restoreState(editor);
061: editor.setUpdateFlag(REFRAME);
062:
063: if (postState.modificationCount != preState.modificationCount) {
064: // Buffer was changed.
065: buffer.invalidate();
066: Sidebar
067: .setUpdateFlagInAllFrames(SIDEBAR_MODIFIED_BUFFER_COUNT
068: | SIDEBAR_REPAINT_BUFFER_LIST);
069: Sidebar.repaintBufferListInAllFrames();
070: }
071: }
072:
073: public void redo() {
074: super .redo();
075: final Editor editor = Editor.currentEditor();
076: Debug.assertTrue(editor.getBuffer() == buffer);
077: postState.restoreState(editor);
078: editor.setUpdateFlag(REFRAME);
079:
080: if (postState.modificationCount != preState.modificationCount) {
081: // Buffer was changed.
082: buffer.invalidate();
083: Sidebar
084: .setUpdateFlagInAllFrames(SIDEBAR_MODIFIED_BUFFER_COUNT
085: | SIDEBAR_REPAINT_BUFFER_LIST);
086: Sidebar.repaintBufferListInAllFrames();
087: }
088: }
089:
090: private class State {
091: final int dotLineNumber;
092: final int dotOffset;
093: final int markLineNumber;
094: final int markOffset;
095: final int absCaretCol;
096: final boolean isColumnSelection;
097: final int modificationCount;
098: final boolean modified;
099: final Line line;
100:
101: State(Editor editor) {
102: final Line dotLine = editor.getDotLine();
103: dotLineNumber = dotLine.lineNumber();
104: final int length = dotLine.length();
105: final int offset = editor.getDotOffset();
106: if (offset > length)
107: Debug.bug();
108: dotOffset = offset > length ? length : offset;
109: absCaretCol = editor.getAbsoluteCaretCol();
110: Position mark = editor.getMark();
111: if (mark != null) {
112: markLineNumber = mark.lineNumber();
113: markOffset = mark.getOffset();
114: } else {
115: markLineNumber = -1;
116: markOffset = -1;
117: }
118: isColumnSelection = editor.isColumnSelection();
119: final Buffer buffer = editor.getBuffer();
120: modificationCount = buffer.getModCount();
121: modified = buffer.isModified();
122: line = buffer.getLine(changeLineNumber).copy();
123: }
124:
125: State(Buffer buffer) {
126: dotLineNumber = -1;
127: dotOffset = -1;
128: absCaretCol = -1;
129: markLineNumber = -1;
130: markOffset = -1;
131: isColumnSelection = false;
132: modificationCount = buffer.getModCount();
133: modified = buffer.isModified();
134: line = buffer.getLine(changeLineNumber).copy();
135: }
136:
137: void restoreState(Editor editor) {
138: Debug.assertTrue(editor.getBuffer() == buffer);
139: Debug.assertTrue(changeLineNumber >= 0);
140:
141: if (!buffer.isWriteLocked())
142: Debug.bug();
143: Line changeLine = buffer.getLine(changeLineNumber);
144: changeLine.copy(line);
145: Editor.updateInAllEditors(changeLine);
146:
147: buffer.setModCount(modificationCount);
148:
149: boolean wasMarked = editor.getMark() != null;
150: editor.updateDotLine();
151: editor.setDot(dotLineNumber, dotOffset);
152: if (dotOffset > editor.getDotLine().length()) {
153: Debug.bug();
154: editor.getDot().setOffset(editor.getDotLine().length());
155: }
156: if (markLineNumber >= 0) {
157: editor.setMark(markLineNumber, markOffset);
158: editor.setColumnSelection(isColumnSelection);
159: } else
160: editor.setMark(null);
161: editor.updateDotLine();
162: final Display display = editor.getDisplay();
163: if (absCaretCol >= 0)
164: display.setCaretCol(absCaretCol - display.getShift());
165: if (wasMarked || editor.getMark() != null)
166: display.setUpdateFlag(REPAINT);
167: }
168: }
169: }
|