001: //This is free software; for terms and warranty disclaimer see ./COPYING.
002:
003: package gnu.jemacs.swt;
004:
005: import gnu.jemacs.buffer.Buffer;
006: import gnu.jemacs.buffer.EKeymap;
007: import gnu.jemacs.buffer.EWindow;
008:
009: import org.eclipse.swt.SWT;
010: import org.eclipse.swt.custom.SashForm;
011: import org.eclipse.swt.custom.VerifyKeyListener;
012: import org.eclipse.swt.events.FocusEvent;
013: import org.eclipse.swt.events.FocusListener;
014: import org.eclipse.swt.events.KeyEvent;
015: import org.eclipse.swt.events.KeyListener;
016: import org.eclipse.swt.events.MouseEvent;
017: import org.eclipse.swt.events.MouseListener;
018: import org.eclipse.swt.events.VerifyEvent;
019: import org.eclipse.swt.widgets.Composite;
020:
021: /**
022: * @author Christian Surlykke
023: * 11-07-2004
024: */
025: public class SwtWindow extends EWindow implements VerifyKeyListener,
026: FocusListener, KeyListener, MouseListener {
027: private SwtWindowWidget swtWindowWidget;
028: private SwtBuffer swtBuffer;
029:
030: public SwtWindow(Buffer buffer) {
031: this (buffer, true);
032: }
033:
034: public SwtWindow(Buffer buffer, boolean wantModeLine) {
035: super (buffer);
036: this .swtBuffer = (SwtBuffer) buffer;
037: updateModeline();
038: }
039:
040: /**
041: *
042: */
043: public void getReadyToShow(final Composite parent,
044: final int firstVisibleLine) {
045: SwtHelper.getDisplay().syncExec(new Runnable() {
046: public void run() {
047: swtWindowWidget = new SwtWindowWidget(parent, swtBuffer
048: .getBufferContent(), firstVisibleLine);
049: swtWindowWidget.getStyledText().addVerifyKeyListener(
050: SwtWindow.this );
051: swtWindowWidget.getStyledText().addKeyListener(
052: SwtWindow.this );
053: swtWindowWidget.getStyledText().addFocusListener(
054: SwtWindow.this );
055: swtWindowWidget.getStyledText().addMouseListener(
056: SwtWindow.this );
057: swtWindowWidget.getStyledText().forceFocus();
058: swtWindowWidget.getStyledText().setCaretOffset(
059: swtBuffer.getDot());
060: }
061: });
062: updateModeline();
063: }
064:
065: /**
066: * @see gnu.jemacs.buffer.EWindow#setBuffer(gnu.jemacs.buffer.Buffer)
067: */
068: public void setBuffer(Buffer buffer) {
069: super .setBuffer(buffer);
070: this .swtBuffer = (SwtBuffer) buffer;
071: if (swtWindowWidget != null) {
072: SwtHelper.setContent(swtWindowWidget.getStyledText(),
073: swtBuffer.getBufferContent());
074: updateModeline();
075: }
076: }
077:
078: /**
079: * The purpose of this method is to emulate the 'toInt' method of SwingWindow
080: * so as to transform Swt KeyEvents into the same int's as equivalent awt KeyEvents.
081: *
082: * TODO: Elaborate this method so that all KeyEvents work (e.g. enter (!))
083: *
084: * I've been thinkin it perhaps would be better to make EKeymap abstract with implementors
085: * for each toolkit, and then lookup commands by Swt events directly when running
086: * Swt and Swing events when running swing. Must be considered more...
087: *
088: *
089: * @param swtKeyCode
090: * @param stateMask
091: * @param additionalFlags
092: * @return
093: */
094: private int transFormKeyKode(int swtKeyCode, int stateMask,
095: int additionalFlags) {
096: int characterPart = Character
097: .toUpperCase((char) (swtKeyCode & 0xFFFF));
098: int modifierPart = (stateMask & swtModifiers) >> 1; // awt modifiers seem to be displaced
099: // one bit to the left relative to
100: // swt modifiers.
101: return characterPart | modifierPart | (additionalFlags << 16);
102: }
103:
104: private final static int swtModifiers = SWT.SHIFT | SWT.CTRL
105: | SWT.ALT;
106:
107: public void handleKey(int code) {
108: Object command = lookupKey(code);
109: if (command == null) {
110: return;
111: }
112: pushPrefix(code);
113: pendingLength--;
114: handleCommand(command);
115: }
116:
117: public void handleCommand(Object command) {
118: int oldDot = getBuffer().getDot();
119: super .handleCommand(command);
120: updateModeline();
121: if (oldDot != getBuffer().getDot()) {
122: swtWindowWidget.getStyledText().showSelection();
123: }
124: }
125:
126: /**
127: * @see gnu.jemacs.buffer.EWindow#setSelected()
128: */
129: public void setSelected() {
130: super .setSelected();
131: buffer.pointMarker.sequence = null;
132: }
133:
134: /**
135: * @see gnu.jemacs.buffer.EWindow#unselect()
136: */
137: public void unselect() {
138: }
139:
140: /**
141: * @see gnu.jemacs.buffer.EWindow#getPoint()
142: */
143: public int getPoint() {
144: return SwtHelper
145: .getCaretOffset(swtWindowWidget.getStyledText());
146: }
147:
148: /**
149: * @see gnu.jemacs.buffer.EWindow#setDot(int)
150: */
151: public void setDot(int offset) {
152: SwtHelper.setCaretOffset(swtWindowWidget.getStyledText(),
153: offset);
154: }
155:
156: public EWindow split(Buffer buffer, int lines, boolean horizontal) {
157: SwtWindow newWindow = new SwtWindow(buffer);
158: newWindow.frame = this .frame;
159: linkSibling(newWindow, horizontal);
160:
161: int firstVisibleLine = buffer == this .buffer ? SwtHelper
162: .getTopIndex(swtWindowWidget.getStyledText()) : 0;
163: int visibleLines = SwtHelper.getArea(swtWindowWidget
164: .getStyledText()).height
165: / SwtHelper.getLineHeight(swtWindowWidget
166: .getStyledText());
167:
168: int[] weights = null;
169: if (!horizontal && lines > 0 && visibleLines > 1) {
170: weights = new int[2];
171: lines = Math.min(lines, visibleLines - 1);
172: weights[0] = lines;
173: weights[1] = visibleLines - lines;
174: }
175:
176: SwtHelper.injectSashFormAsParent(swtWindowWidget,
177: horizontal ? SWT.HORIZONTAL : SWT.VERTICAL);
178: newWindow.getReadyToShow(SwtHelper.getParent(swtWindowWidget),
179: firstVisibleLine);
180: if (weights != null)
181: SwtHelper.setWeights(((SashForm) SwtHelper
182: .getParent(swtWindowWidget)), weights);
183: SwtHelper.layout(SwtHelper.getParent(SwtHelper
184: .getParent(swtWindowWidget)));
185:
186: return newWindow;
187: }
188:
189: /**
190: * @see gnu.jemacs.buffer.EWindow#getCharSize()
191: */
192: protected void getCharSize() {
193: // TODO
194: }
195:
196: /**
197: * @see gnu.jemacs.buffer.EWindow#getWidth()
198: */
199: public int getWidth() {
200: return SwtHelper.getArea(swtWindowWidget.getStyledText()).width;
201: }
202:
203: /**
204: * @see gnu.jemacs.buffer.EWindow#getHeight()
205: */
206: public int getHeight() {
207: return SwtHelper.getArea(swtWindowWidget.getStyledText()).height;
208: }
209:
210: /**
211: * @see gnu.jemacs.buffer.EWindow#tooLong(int)
212: */
213: public Object tooLong(int pendingLength) {
214: // TODO Something more subtle here
215: return null;
216: }
217:
218: // ---------------------------- Listener methods ------------------------------------
219:
220: // --- VerifyKeyListener
221: public void verifyKey(VerifyEvent event) {
222: event.doit = false;
223: }
224:
225: // --- FocusListener ---
226: public void focusGained(FocusEvent e) {
227: setSelected();
228: }
229:
230: public void focusLost(FocusEvent e) {
231: unselect();
232: }
233:
234: // --- KeyListener ---
235: public void keyPressed(KeyEvent e) {
236: handleKey(SwtKeyMapper.swtKey2EKey(e));
237: SwtHelper.setCaretOffset(swtWindowWidget.getStyledText(),
238: buffer.getDot());
239: }
240:
241: public void keyReleased(KeyEvent e) {
242: }
243:
244: // --- MouseListener ---
245: public void mouseDoubleClick(MouseEvent e) {
246: }
247:
248: public void mouseDown(MouseEvent e) {
249: if (EWindow.getSelected() == this ) // Is this nessecary - aren't we always selected when this event arrives?
250: {
251: buffer.setDot(SwtHelper.getCaretOffset(swtWindowWidget
252: .getStyledText()));
253: SwtHelper.showSelection(swtWindowWidget.getStyledText());
254: }
255: }
256:
257: public void mouseUp(MouseEvent e) {
258: }
259:
260: /**
261: * @param e
262: */
263: public static void show(KeyEvent e) {
264: System.out.println("keyCode: " + EKeymap.show(e.keyCode));
265: System.out.println("character: " + EKeymap.show(e.character));
266: System.out.println("stateMask: " + EKeymap.show(e.stateMask));
267: }
268:
269: public void updateModeline() {
270: if (swtWindowWidget != null) {
271: SwtHelper.getDisplay().asyncExec(new Runnable() {
272: public void run() {
273: swtWindowWidget.getModeline().setText(
274: swtBuffer.getModelineFormat().toString());
275: }
276: });
277: }
278: }
279:
280: }
|