001: /*
002: * Anchor.java - A base point for physical line <-> screen line conversion
003: * :tabSize=8:indentSize=8:noTabs=false:
004: * :folding=explicit:collapseFolds=1:
005: *
006: * Copyright (C) 2005 Slava Pestov
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: */
022:
023: package org.gjt.sp.jedit.textarea;
024:
025: import org.gjt.sp.jedit.Debug;
026: import org.gjt.sp.util.Log;
027:
028: /**
029: * A base point for physical line/screen line conversion.
030: * @author Slava Pestov
031: * @version $Id: Anchor.java 10751 2007-09-25 20:27:37Z kpouer $
032: */
033: abstract class Anchor {
034: final DisplayManager displayManager;
035: final TextArea textArea;
036: /** The physical line. */
037: int physicalLine;
038: /**
039: * The visible line index. (from the top of the buffer). It can be different from physical line
040: * when using soft wrap.
041: */
042: int scrollLine;
043: boolean callChanged;
044: boolean callReset;
045:
046: //{{{ Anchor constructor
047: protected Anchor(DisplayManager displayManager, TextArea textArea) {
048: this .displayManager = displayManager;
049: this .textArea = textArea;
050: } //}}}
051:
052: abstract void reset();
053:
054: abstract void changed();
055:
056: //{{{ toString() method
057: public String toString() {
058: return getClass().getName() + '[' + physicalLine + ','
059: + scrollLine + ']';
060: } //}}}
061:
062: //{{{ contentInserted() method
063: /**
064: * Some content is inserted.
065: *
066: * @param startLine the start of the insert
067: * @param numLines the number of insterted lines
068: */
069: void contentInserted(int startLine, int numLines) {
070: // The Anchor is changed only if the content was inserted before
071: if (physicalLine >= startLine) {
072: if (physicalLine != startLine)
073: physicalLine += numLines;
074: callChanged = true;
075: }
076: } //}}}
077:
078: //{{{ preContentRemoved() method
079: /**
080: * Method called before a content is removed from a buffer.
081: *
082: * @param startLine the first line of the removed content
083: * @param offset the offset in the start line
084: * @param numLines the number of removed lines
085: */
086: void preContentRemoved(int startLine, int offset, int numLines) {
087: if (Debug.SCROLL_DEBUG)
088: Log.log(Log.DEBUG, this , "preContentRemoved() before:"
089: + this );
090: // The removed content starts before the Anchor, we need to pull the anchor up
091: if (physicalLine >= startLine) {
092: if (physicalLine == startLine)
093: callChanged = true;
094: else {
095: int end = Math.min(startLine + numLines, physicalLine);
096: //Check the lines from the beginning of the removed content to the end (or the physical
097: //line of the Anchor if it is before the end of the removed content
098:
099: int loopStart = startLine + 1;
100:
101: //{{{ treatment if the beginning of the deleted content is inside a physical line that has several line counts
102: if (displayManager.isLineVisible(startLine)) {
103: int screenLineCount = displayManager.screenLineMgr
104: .getScreenLineCount(startLine);
105: if (screenLineCount > 1) {
106: int lineStartOffset = textArea
107: .getLineStartOffset(startLine);
108:
109: int startScreenLine = textArea
110: .getScreenLineOfOffset(lineStartOffset);
111: int deleteStartScreenLine = textArea
112: .getScreenLineOfOffset(offset);
113: if (startScreenLine != deleteStartScreenLine) {
114: loopStart = startLine + 2;
115: scrollLine -= screenLineCount
116: - deleteStartScreenLine
117: + startScreenLine;
118: }
119: }
120: }
121: //}}}
122:
123: for (int i = loopStart; i <= end; i++) {
124: //XXX
125: if (displayManager.isLineVisible(i - 1)) {
126: scrollLine -= displayManager.screenLineMgr
127: .getScreenLineCount(i - 1);
128: }
129: }
130: physicalLine -= end - startLine;
131: callChanged = true;
132: }
133: }
134: if (Debug.SCROLL_DEBUG)
135: Log.log(Log.DEBUG, this , "preContentRemoved() after:"
136: + this );
137: } //}}}
138: }
|