001: /*
002: * ChangeMarks.java
003: *
004: * Copyright (C) 2002 Peter Graves
005: * $Id: ChangeMarks.java,v 1.1.1.1 2002/09/24 16:09:20 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.CompoundEdit;
025:
026: public final class ChangeMarks implements Constants {
027: public static void nextChange() {
028: final Editor editor = Editor.currentEditor();
029: if (editor.getDot() == null)
030: return;
031: Line line = editor.getDotLine();
032: // Advance to first unmodified line.
033: while (line.isModified()) {
034: line = line.next();
035: if (line == null)
036: break;
037: }
038: if (line != null) {
039: Debug.assertTrue(!line.isModified());
040: // Advance to next modified line.
041: while (!line.isModified()) {
042: line = line.next();
043: if (line == null)
044: break;
045: }
046: }
047: if (line != null) {
048: Debug.assertTrue(line.isModified());
049: editor.moveDotTo(line, 0);
050: } else
051: editor.status("No more changes");
052: }
053:
054: public static void previousChange() {
055: final Editor editor = Editor.currentEditor();
056: if (editor.getDot() == null)
057: return;
058: Line line = editor.getDotLine();
059: // Go back to last unmodified line.
060: while (line.isModified()) {
061: line = line.previous();
062: if (line == null)
063: break;
064: }
065: if (line != null) {
066: Debug.assertTrue(!line.isModified());
067: // Go back to last modified line.
068: while (!line.isModified()) {
069: line = line.previous();
070: if (line == null)
071: break;
072: }
073: }
074: if (line != null) {
075: Debug.assertTrue(line.isModified());
076: editor.moveDotTo(line, 0);
077: } else
078: editor.status("No more changes");
079: }
080:
081: public static void revertLines() {
082: final Editor editor = Editor.currentEditor();
083: final Position dot = editor.getDot(); // Alias.
084: if (dot == null)
085: return;
086: if (editor.isColumnSelection()) {
087: editor.notSupportedForColumnSelections();
088: return;
089: }
090: final Position mark = editor.getMark(); // Alias.
091: final Line dotLine = editor.getDotLine();
092: Line before, last;
093: if (mark != null) {
094: Region r = new Region(editor);
095: before = r.getBeginLine().previous();
096: last = r.getEndLine();
097: } else {
098: before = dotLine.previous();
099: last = dotLine;
100: }
101: // Find last unmodified line above dot or beginning of marked region.
102: while (before != null && before.isModified())
103: before = before.previous();
104: // Find last modified line in current group of changed lines.
105: for (Line line = last.next(); line != null; line = line.next()) {
106: if (line.isModified())
107: last = line;
108: else
109: break;
110: }
111: // Make sure at least one of the lines in question is in fact modified.
112: boolean modified = false;
113: for (Line line = last; line != before; line = line.previous()) {
114: if (line.isModified()) {
115: modified = true;
116: break;
117: }
118: }
119: if (!modified)
120: return; // Nothing to revert.
121: CompoundEdit compoundEdit = editor.beginCompoundEdit();
122: editor.addUndo(SimpleEdit.MOVE);
123: if (mark != null) {
124: editor.setMark(null);
125: editor.setUpdateFlag(REPAINT);
126: }
127: dot.moveTo(last, 0);
128: revertLine(editor, dot.getLine());
129: while (dot.getPreviousLine() != before) {
130: editor.addUndo(SimpleEdit.MOVE);
131: dot.moveTo(dot.getPreviousLine(), 0);
132: revertLine(editor, dot.getLine());
133: }
134: editor.moveCaretToDotCol();
135: editor.endCompoundEdit(compoundEdit);
136: }
137:
138: private static void revertLine(Editor editor, Line line) {
139: if (!line.isModified())
140: return;
141: final Buffer buffer = editor.getBuffer();
142: try {
143: buffer.lockWrite();
144: } catch (InterruptedException e) {
145: Log.error(e);
146: return;
147: }
148: try {
149: if (line.isNew())
150: revertNewLine(editor, line);
151: else
152: revertChangedLine(editor, line);
153: } finally {
154: buffer.unlockWrite();
155: }
156: }
157:
158: private static void revertNewLine(Editor editor, final Line dotLine) {
159: editor.adjustMarkers(dotLine);
160: final Line prev = dotLine.previous();
161: final Line next = dotLine.next();
162: if (prev == null && next == null)
163: return;
164: CompoundEdit compoundEdit = editor.beginCompoundEdit();
165: compoundEdit.addEdit(new UndoMove(editor));
166: final Position dot = editor.getDot(); // Alias.
167: boolean insertBefore;
168: if (next != null) {
169: dot.moveTo(next, 0);
170: insertBefore = true;
171: } else {
172: dot.moveTo(prev, 0);
173: insertBefore = false;
174: }
175: editor.moveCaretToDotCol();
176: final Buffer buffer = editor.getBuffer();
177: compoundEdit.addEdit(new UndoRemoveLine(editor, insertBefore));
178: if (prev != null)
179: prev.setNext(next);
180: else
181: buffer.setFirstLine(next);
182: if (next != null)
183: next.setPrevious(prev);
184: buffer.renumber();
185: buffer.modified();
186: editor.endCompoundEdit(compoundEdit);
187: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
188: Editor ed = it.nextEditor();
189: if (ed.getTopLine() == dotLine)
190: ed.setTopLine(dot.getLine());
191: }
192: buffer.repaint();
193: }
194:
195: private static void revertChangedLine(Editor editor,
196: final Line dotLine) {
197: final Buffer buffer = editor.getBuffer();
198: final Position dot = editor.getDot(); // Alias.
199: final String originalText = dotLine.getOriginalText();
200: if (originalText != null) {
201: CompoundEdit compoundEdit = editor.beginCompoundEdit();
202: final int index = originalText.indexOf('\n');
203: if (index >= 0) {
204: // Multi-line change.
205: final Line begin = dotLine;
206: final Line end = dotLine.next();
207: editor.addUndo(SimpleEdit.LINE_EDIT);
208: dotLine.setText(originalText.substring(0, index));
209: buffer.modified();
210: editor.addUndo(SimpleEdit.MOVE);
211: dot.setOffset(dotLine.length());
212: editor.addUndo(SimpleEdit.INSERT_STRING);
213: buffer.insertString(dot, originalText.substring(index));
214: for (Line line = begin; line != end; line = line.next())
215: line.unmodified();
216: } else {
217: // Single line change.
218: editor.addUndo(SimpleEdit.LINE_EDIT);
219: dotLine.setText(originalText);
220: dotLine.unmodified();
221: Editor.updateInAllEditors(dotLine);
222: buffer.modified();
223: if (dot.getOffset() > dotLine.length()) {
224: editor.addUndo(SimpleEdit.MOVE);
225: dot.setOffset(dotLine.length());
226: }
227: }
228: editor.moveCaretToDotCol();
229: editor.endCompoundEdit(compoundEdit);
230: }
231: }
232:
233: public static void changes() {
234: final Editor editor = Editor.currentEditor();
235: final Buffer buffer = editor.getBuffer();
236: final File file = buffer.getFile();
237: if (file == null || file.isRemote())
238: return;
239: final File tempFile = Utilities.getTempFile();
240: if (tempFile == null)
241: return;
242: if (buffer.writeFile(tempFile)) {
243: FastStringBuffer sb = new FastStringBuffer("diff -u ");
244: // Enclose filenames in double quotes if they contain embedded
245: // spaces.
246: String name1 = file.canonicalPath();
247: if (name1.indexOf(' ') >= 0) {
248: sb.append('"');
249: sb.append(name1);
250: sb.append('"');
251: } else
252: sb.append(name1);
253: sb.append(' ');
254: String name2 = tempFile.canonicalPath();
255: if (name2.indexOf(' ') >= 0) {
256: sb.append('"');
257: sb.append(name2);
258: sb.append('"');
259: } else
260: sb.append(name2);
261: final String cmd = sb.toString();
262: ShellCommand shellCommand = new ShellCommand(cmd);
263: shellCommand.run();
264: // Kill existing diff output buffer if any for same parent buffer.
265: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
266: Buffer b = it.nextBuffer();
267: if (b instanceof DiffOutputBuffer) {
268: if (((DiffOutputBuffer) b).getParentBuffer() == buffer) {
269: if (((DiffOutputBuffer) b).getVCType() == 0) {
270: b.kill();
271: break; // There should be one at most.
272: }
273: }
274: }
275: }
276: String output = shellCommand.getOutput();
277: if (output.length() == 0) {
278: MessageDialog.showMessageDialog(editor, "No changes",
279: buffer.getFile().getName());
280: } else {
281: DiffOutputBuffer outputBuffer = new DiffOutputBuffer(
282: buffer, output, 0);
283: sb.setLength(0);
284: sb.append("diff -ub ");
285: sb.append(file.getName());
286: sb.append(' ');
287: sb.append(tempFile.canonicalPath());
288: outputBuffer.setTitle(sb.toString());
289: editor.makeNext(outputBuffer);
290: editor.activateInOtherWindow(outputBuffer);
291: }
292: }
293: if (tempFile.isFile())
294: tempFile.delete();
295: }
296: }
|