blob: 54c6285adcb5674439d2f0e31ef65c06436af17e [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
*******************************************************************************/
package com.google.eclipse.elt.emulator.internal.model;
import org.eclipse.core.runtime.Assert;
import com.google.eclipse.elt.emulator.model.*;
/**
* 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'} and {@code style=null}.
*/
public class TerminalTextDataWindow implements ITerminalTextData {
private final ITerminalTextData data;
private int windowStartLine;
private int windowSize;
private int height;
private int maxHeight;
public TerminalTextDataWindow(ITerminalTextData data) {
this.data = data;
}
public TerminalTextDataWindow() {
this(new TerminalTextDataStore());
}
private boolean isInWindow(int line) {
return line >= windowStartLine && line < windowStartLine + windowSize;
}
@Override public char getChar(int line, int column) {
if (!isInWindow(line)) {
return 0;
}
return data.getChar(line - windowStartLine, column);
}
@Override public char[] getChars(int line) {
if (!isInWindow(line)) {
return null;
}
return data.getChars(line - windowStartLine);
}
@Override public int getHeight() {
return height;
}
@Override public LineSegment[] getLineSegments(int line, int startingColumn, int columnCount) {
if (!isInWindow(line)) {
return new LineSegment[] { new LineSegment(startingColumn, new String(new char[columnCount]), null) };
}
return data.getLineSegments(line - windowStartLine, startingColumn, columnCount);
}
@Override public int getMaxHeight() {
return maxHeight;
}
@Override public Style getStyle(int line, int column) {
if (!isInWindow(line)) {
return null;
}
return data.getStyle(line - windowStartLine, column);
}
@Override public Style[] getStyles(int line) {
if (!isInWindow(line)) {
return null;
}
return data.getStyles(line - windowStartLine);
}
@Override public int getWidth() {
return data.getWidth();
}
@Override public ITerminalTextDataSnapshot makeSnapshot() {
throw new UnsupportedOperationException();
}
@Override public void addLine() {
if (maxHeight > 0 && getHeight() < maxHeight) {
setDimensions(getHeight() + 1, getWidth());
} else {
scroll(0, getHeight(), -1);
}
}
@Override public void copy(ITerminalTextData source) {
// We inherit the dimensions of the source.
setDimensions(source.getHeight(), source.getWidth());
int n = Math.min(windowSize, source.getHeight() - windowStartLine);
if (n > 0) {
data.copyRange(source, windowStartLine, 0, n);
}
}
@Override public void copyRange(ITerminalTextData source, int sourceStartLine, int destinationStartLine, int length) {
int newLength = length;
int destinationStart = destinationStartLine - windowStartLine;
int sourceStart = sourceStartLine;
// If start outside our range, cut the length to copy.
if (destinationStart < 0) {
newLength += destinationStart;
sourceStart -= destinationStart;
destinationStart = 0;
}
// Do not exceed the window size.
newLength = Math.min(newLength, windowSize);
if (newLength > 0) {
data.copyRange(source, sourceStart, destinationStart, newLength);
}
}
@Override public void copyLine(ITerminalTextData source, int sourceLine, int destLine) {
if (isInWindow(destLine)) {
data.copyLine(source, sourceLine, destLine - windowStartLine);
}
}
@Override public void scroll(int startLine, int lineCount, int shift) {
Assert.isTrue(startLine >= 0 && startLine + lineCount <= height);
int length = lineCount;
int start = startLine - windowStartLine;
// If start outside our range, cut the length to copy.
if (start < 0) {
length += start;
start = 0;
}
length = Math.min(length, windowSize - start);
// do not exceed the window size
if (length > 0) {
data.scroll(start, length, shift);
}
}
@Override public void setChar(int line, int column, char c, Style style) {
if (!isInWindow(line)) {
return;
}
data.setChar(line - windowStartLine, column, c, style);
}
@Override public void setChars(int line, int column, char[] chars, int start, int len, Style style) {
if (!isInWindow(line)) {
return;
}
data.setChars(line - windowStartLine, column, chars, start, len, style);
}
@Override public void setChars(int line, int column, char[] chars, Style style) {
if (!isInWindow(line)) {
return;
}
data.setChars(line - windowStartLine, column, chars, style);
}
@Override public void setDimensions(int height, int width) {
Assert.isTrue(height >= 0);
data.setDimensions(windowSize, width);
setHeight(height);
}
@Override public void setMaxHeight(int maxHeight) {
this.maxHeight = maxHeight;
}
public void setWindow(int startLine, int size) {
windowStartLine = startLine;
windowSize = size;
data.setDimensions(windowSize, getWidth());
}
public int getWindowStartLine() {
return windowStartLine;
}
public int getWindowSize() {
return windowSize;
}
public void setHeight(int height) {
this.height = height;
}
@Override public void cleanLine(int line) {
if (isInWindow(line)) {
data.cleanLine(line - windowStartLine);
}
}
@Override public int getCursorColumn() {
return data.getCursorColumn();
}
@Override public int getCursorLine() {
return data.getCursorLine();
}
@Override public void setCursorColumn(int column) {
data.setCursorColumn(column);
}
@Override public void setCursorLine(int line) {
data.setCursorLine(line);
}
}