Programming/Eclipse RCP

Undo/Redo 기능 추가 StyledText

Lawmin 2012. 1. 2. 11:48
delta 값 기록 방식이 아닌 전체 이미지 저장하는 방식이라 커서 위치 복원 문제나 메모리 과다 사용 문제가 있을 수 있다.
event listener를 이용해 caret pos, replaced text, replacing text 등을 얻어와 처리할 수는 있을 것 같다. 

import java.util.LinkedList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Composite;

public class HistoryStyledText extends StyledText {
private class UndoInfo {
String text;
int cursorIndex = 0;
private UndoInfo(String text, int cursorIndex) {
this.text = text;
this.cursorIndex = cursorIndex;
}
}
private List undoStack;
private int undoIndex;
private boolean isModifyEventOn; 
public HistoryStyledText(Composite parent, int style) {
super(parent, style);
undoStack = new LinkedList();
   
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if((e.stateMask & SWT.CTRL) != 0) {
if(e.keyCode == 122) {
isModifyEventOn = false;
undo();
isModifyEventOn = true;
return;
}
else if(e.keyCode == 121) {
isModifyEventOn = false;
redo();
isModifyEventOn = true;
return;
}
}
}
});
addExtendedModifyListener(new ExtendedModifyListener() {
public void modifyText(ExtendedModifyEvent event) {
if(isModifyEventOn) {
UndoInfo undo = new UndoInfo(getText(), getCaretOffset());
++undoIndex;
undoStack.add(undoIndex, undo);
}
}
});
Font traceFont = new Font(null, "Fixedsys", 10, SWT.NORMAL);
setFont(traceFont);
undoIndex = 0;
undoStack.add(0, new UndoInfo("", 0));
isModifyEventOn = true;
}
private void undo() {
if(undoIndex > 0 && undoStack.size() > 0) {
--undoIndex;
UndoInfo undo = (UndoInfo)undoStack.get(undoIndex);
setText(undo.text);
setCaretOffset(undo.cursorIndex);
}
}
private void redo() {
if(undoIndex < undoStack.size() - 1) {
++undoIndex;
UndoInfo undo = (UndoInfo)undoStack.get(undoIndex);
setText(undo.text);
setCaretOffset(undo.cursorIndex);
}
}
}