001: /*
002: * Region.java
003: *
004: * Copyright (C) 1998-2002 Peter Graves
005: * $Id: Region.java,v 1.2 2003/03/20 15:23:42 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 java.util.List;
025:
026: public final class Region implements Constants {
027: private final Buffer buffer;
028: private final Position begin;
029: private final Line beginLine;
030: private final int beginOffset;
031: private Position end;
032: private Line endLine;
033: private int endOffset;
034: private boolean isColumnRegion;
035: private int beginCol = -1;
036: private int endCol = -1;
037:
038: // It is not necessary that pos1 come before pos2; we figure that out on
039: // the fly.
040: public Region(Buffer buffer, Position pos1, Position pos2) {
041: this .buffer = buffer;
042: if (buffer.needsRenumbering())
043: buffer.renumber();
044: if (pos1.isBefore(pos2)) {
045: begin = new Position(pos1);
046: end = new Position(pos2);
047: } else {
048: begin = new Position(pos2);
049: end = new Position(pos1);
050: }
051: beginLine = begin.getLine();
052: beginOffset = begin.getOffset();
053: endLine = end.getLine();
054: endOffset = end.getOffset();
055: }
056:
057: public Region(Editor editor) {
058: this (editor.getBuffer(), editor.getMark(), editor.getDot());
059: if (editor.isColumnSelection()) {
060: isColumnRegion = true;
061: if (begin.equals(editor.getMark())) {
062: beginCol = buffer.getCol(begin);
063: endCol = editor.getDisplay().getAbsoluteCaretCol();
064: } else {
065: beginCol = editor.getDisplay().getAbsoluteCaretCol();
066: endCol = buffer.getCol(end);
067: }
068: }
069: }
070:
071: public final Buffer getBuffer() {
072: return buffer;
073: }
074:
075: public final Position getBegin() {
076: return begin;
077: }
078:
079: public final Line getBeginLine() {
080: return beginLine;
081: }
082:
083: public final int getBeginLineNumber() {
084: return beginLine.lineNumber();
085: }
086:
087: public final int getBeginOffset() {
088: return beginOffset;
089: }
090:
091: public final int getBeginCol() {
092: if (beginCol < 0)
093: beginCol = buffer.getCol(begin);
094: return beginCol;
095: }
096:
097: public final Position getEnd() {
098: return end;
099: }
100:
101: public final void setEnd(Position pos) {
102: end = pos;
103: endLine = end.getLine();
104: endOffset = end.getOffset();
105: endCol = -1;
106: }
107:
108: public final Line getEndLine() {
109: return endLine;
110: }
111:
112: public final int getEndLineNumber() {
113: return endLine.lineNumber();
114: }
115:
116: public final int getEndOffset() {
117: return endOffset;
118: }
119:
120: public final void setEndOffset(int offset) {
121: end.setOffset(offset);
122: endOffset = offset;
123: }
124:
125: public final int getEndCol() {
126: if (endCol < 0)
127: endCol = buffer.getCol(end);
128: return endCol;
129: }
130:
131: public final boolean isColumnRegion() {
132: return isColumnRegion;
133: }
134:
135: public final boolean isLineRegion() {
136: return beginOffset == 0 && endOffset == 0;
137: }
138:
139: public String toString() {
140: if (beginLine == endLine)
141: return beginLine.substring(beginOffset, endOffset);
142:
143: FastStringBuffer sb = new FastStringBuffer();
144: if (isColumnRegion) {
145: for (Line line = beginLine; line != null; line = line
146: .next()) {
147: sb.append(getTextInRegion(line));
148: sb.append('\n');
149: if (line == getEndLine())
150: break;
151: }
152: } else {
153: sb.append(beginLine.substring(beginOffset));
154: sb.append('\n');
155: Line line = beginLine.next();
156: while (line != endLine && line != null) {
157: sb.append(line.getText());
158: sb.append('\n');
159: line = line.next();
160: }
161: if (line == endLine)
162: sb.append(line.substring(0, endOffset));
163: }
164: return sb.toString();
165: }
166:
167: private String getTextInRegion(Line line) {
168: String text = Utilities.detab(line.getText(), buffer
169: .getTabWidth());
170: if (text.length() > getEndCol())
171: return text.substring(getBeginCol(), getEndCol());
172: else if (text.length() > getBeginCol())
173: return text.substring(getBeginCol());
174: else
175: return "";
176: }
177:
178: public boolean adjustMarker(Position pos) {
179: if (pos == null)
180: return false;
181: final Line line = pos.getLine();
182: final int offset = pos.getOffset();
183: if (line == null)
184: return false;
185: if (line == beginLine) {
186: if (line == endLine && offset > endOffset) {
187: pos.setOffset(offset - (endOffset - beginOffset));
188: return true;
189: }
190: if (offset > beginOffset) {
191: pos.setOffset(beginOffset);
192: return true;
193: }
194: return false;
195: }
196: if (line == endLine) {
197: if (offset <= endOffset)
198: pos.moveTo(begin);
199: else
200: pos.moveTo(beginLine, beginOffset + offset - endOffset);
201: return true;
202: }
203: if (pos.lineNumber() > begin.lineNumber()
204: && pos.lineNumber() < end.lineNumber()) {
205: pos.moveTo(begin);
206: return true;
207: }
208: return false;
209: }
210:
211: private void adjustMarkers() {
212: if (Editor.getEditorCount() > 1) {
213: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
214: Editor ed = it.nextEditor();
215: if (ed == Editor.currentEditor())
216: continue;
217: if (ed.getBuffer() == buffer) {
218: // Buffer is displayed in another frame.
219: if (adjustMarker(ed.getDot()))
220: ed.moveCaretToDotCol();
221: if (adjustMarker(ed.getMark()))
222: ed.setMark(null); // Not taking any chances.
223: Position top = new Position(ed.getTopLine(), 0);
224: if (adjustMarker(top)) {
225: ed.setTopLine(top.getLine());
226: ed.setUpdateFlag(REPAINT);
227: }
228: } else {
229: // Not presently displayed, but possibly in a stored view...
230: View view = (View) ed.views.get(buffer);
231: if (view != null) {
232: adjustMarker(view.dot);
233: if (adjustMarker(view.mark))
234: view.mark = null;
235: if (view.topLine != null) {
236: Position top = new Position(view.topLine, 0);
237: if (adjustMarker(top))
238: view.topLine = top.getLine();
239: }
240: }
241: }
242: }
243: }
244: List markers = Marker.getAllMarkers();
245: for (int i = markers.size(); i-- > 0;) {
246: Marker m = (Marker) markers.get(i);
247: if (m != null && m.getBuffer() == buffer)
248: adjustMarker(m.getPosition());
249: }
250: }
251:
252: public void delete() {
253: adjustMarkers();
254: try {
255: buffer.lockWrite();
256: } catch (InterruptedException e) {
257: Log.error(e);
258: return;
259: }
260: try {
261: final String head = beginLine.substring(0, beginOffset);
262: final String tail = endLine.substring(endOffset);
263: if (beginLine == endLine) {
264: beginLine.setText(head.concat(tail));
265: } else {
266: FastStringBuffer sb = new FastStringBuffer();
267: for (Line line = beginLine; line != null; line = line
268: .next()) {
269: // Skip new lines since we just want the original text.
270: if (line != endLine && !line.isNew()) {
271: if (sb.length() > 0)
272: sb.append('\n');
273: String s = line.getOriginalText();
274: sb.append(s != null ? s : line.getText());
275: } else if (line == endLine) {
276: if (!line.isNew()) {
277: if (sb.length() > 0)
278: sb.append('\n');
279: String s = line.getOriginalText();
280: sb.append(s != null ? s : line.getText());
281: }
282: break;
283: }
284: }
285: beginLine.setText(head.concat(tail));
286: beginLine.setOriginalText(sb.toString());
287: // Make adjustments so revertLines() will work correctly...
288: if (beginLine.isNew()) {
289: if (beginLine.getText().equals(
290: beginLine.getOriginalText())) {
291: beginLine.setNew(false);
292: beginLine.setOriginalText(null);
293: }
294: }
295: Line nextLine = endLine.next();
296: beginLine.setNext(nextLine);
297: if (nextLine != null)
298: nextLine.setPrevious(beginLine);
299: buffer.needsRenumbering = true;
300: }
301: buffer.modified();
302: } finally {
303: buffer.unlockWrite();
304: }
305: }
306: }
|