blob: 0c4072cc5b14b12abf52c83b92d21b2065e066ab [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. 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:
* Michael Scharf (Wind River) - initial API and implementation
*******************************************************************************/
package org.eclipse.tm.internal.terminal.model;
import org.eclipse.tm.terminal.model.ITerminalTextData;
import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot;
import org.eclipse.tm.terminal.model.LineSegment;
import org.eclipse.tm.terminal.model.Style;
/**
* This class stores the data only within a window {@link #setWindow(int, int)} and
* {@link #getWindowStartLine()} and {@link #getWindowSize()}. Everything outside
* the is <code>char=='\000'</code> and <code>style=null</code>.
*
*/
public class TerminalTextDataWindow implements ITerminalTextData {
final ITerminalTextData fData;
int fWindowStartLine;
int fWindowSize;
int fHeight;
int fMaxHeight;
public TerminalTextDataWindow(ITerminalTextData data) {
fData=data;
}
public TerminalTextDataWindow() {
this(new TerminalTextDataStore());
}
/**
* This is used in asserts to throw an {@link RuntimeException}.
* This is useful for tests.
* @return never -- throws an exception
*/
private boolean throwRuntimeException() {
throw new RuntimeException();
}
/**
* @param line
* @return true if the line is within the window
*/
boolean isInWindow(int line) {
return line>=fWindowStartLine && line<fWindowStartLine+fWindowSize;
}
public char getChar(int line, int column) {
if(!isInWindow(line))
return 0;
return fData.getChar(line-fWindowStartLine, column);
}
public char[] getChars(int line) {
if(!isInWindow(line))
return null;
return fData.getChars(line-fWindowStartLine);
}
public int getHeight() {
return fHeight;
}
public LineSegment[] getLineSegments(int line, int startCol, int numberOfCols) {
if(!isInWindow(line))
return new LineSegment[]{new LineSegment(startCol,new String(new char[numberOfCols]),null)};
return fData.getLineSegments(line-fWindowStartLine, startCol, numberOfCols);
}
public int getMaxHeight() {
return fMaxHeight;
}
public Style getStyle(int line, int column) {
if(!isInWindow(line))
return null;
return fData.getStyle(line-fWindowStartLine, column);
}
public Style[] getStyles(int line) {
if(!isInWindow(line))
return null;
return fData.getStyles(line-fWindowStartLine);
}
public int getWidth() {
return fData.getWidth();
}
public ITerminalTextDataSnapshot makeSnapshot() {
throw new UnsupportedOperationException();
}
public void addLine() {
if(fMaxHeight>0 && getHeight()<fMaxHeight) {
setDimensions(getHeight()+1, getWidth());
} else {
scroll(0,getHeight(),-1);
}
}
public void copy(ITerminalTextData source) {
// we inherit the dimensions of the source
setDimensions(source.getHeight(), source.getWidth());
int n=Math.min(fWindowSize, source.getHeight()-fWindowStartLine);
if(n>0)
fData.copyRange(source, fWindowStartLine, 0, n);
}
public void copyRange(ITerminalTextData source, int sourceStartLine, int destStartLine, int length) {
int n=length;
int dStart=destStartLine-fWindowStartLine;
int sStart=sourceStartLine;
// if start outside our range, cut the length to copy
if(dStart<0) {
n+=dStart;
sStart-=dStart;
dStart=0;
}
// do not exceed the window size
n=Math.min(n,fWindowSize);
if(n>0)
fData.copyRange(source, sStart, dStart, n);
}
public void copyLine(ITerminalTextData source, int sourceLine, int destLine) {
if(isInWindow(destLine))
fData.copyLine(source, sourceLine, destLine-fWindowStartLine);
}
public void scroll(int startLine, int size, int shift) {
assert (startLine>=0 && startLine+size<=fHeight) || throwRuntimeException();
int n=size;
int start=startLine-fWindowStartLine;
// if start outside our range, cut the length to copy
if(start<0) {
n+=start;
start=0;
}
n=Math.min(n,fWindowSize-start);
// do not exceed the window size
if(n>0)
fData.scroll(start, n, shift);
}
public void setChar(int line, int column, char c, Style style) {
if(!isInWindow(line))
return;
fData.setChar(line-fWindowStartLine, column, c, style);
}
public void setChars(int line, int column, char[] chars, int start, int len, Style style) {
if(!isInWindow(line))
return;
fData.setChars(line-fWindowStartLine, column, chars, start, len, style);
}
public void setChars(int line, int column, char[] chars, Style style) {
if(!isInWindow(line))
return;
fData.setChars(line-fWindowStartLine, column, chars, style);
}
public void setDimensions(int height, int width) {
assert height>=0 || throwRuntimeException();
fData.setDimensions(fWindowSize, width);
fHeight=height;
}
public void setMaxHeight(int height) {
fMaxHeight=height;
}
public void setWindow(int startLine, int size) {
// assert startLine+size<=getHeight()||throwRuntimeException();
fWindowStartLine=startLine;
fWindowSize=size;
fData.setDimensions(fWindowSize, getWidth());
}
public int getWindowStartLine() {
return fWindowStartLine;
}
public int getWindowSize() {
return fWindowSize;
}
public void setHeight(int height) {
fHeight = height;
}
public void cleanLine(int line) {
if(isInWindow(line))
fData.cleanLine(line-fWindowStartLine);
}
public int getCursorColumn() {
return fData.getCursorColumn();
}
public int getCursorLine() {
return fData.getCursorLine();
}
public void setCursorColumn(int column) {
fData.setCursorColumn(column);
}
public void setCursorLine(int line) {
fData.setCursorLine(line);
}
}