summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets
diff options
context:
space:
mode:
authorFelipe Heidrich <felipe_heidrich@ca.ibm.com>2011-12-05 12:19:10 -0500
committerFelipe Heidrich <felipe_heidrich@ca.ibm.com>2011-12-05 12:19:10 -0500
commit3396a784ab92d96b548bec583f27093ab78d5d14 (patch)
tree8bff15f6f2af5a35798e3aef967e35971fc3a8a1 /bundles/org.eclipse.swt/Eclipse SWT Custom Widgets
parent9eaccc1cb16d9d4692cc745cb6ccf9b2b5e4c1f8 (diff)
parent64d29b632ce5e80bcbbf72b8860873b3b0700575 (diff)
downloadeclipse.platform.swt-3396a784ab92d96b548bec583f27093ab78d5d14.tar.gz
eclipse.platform.swt-3396a784ab92d96b548bec583f27093ab78d5d14.tar.xz
eclipse.platform.swt-3396a784ab92d96b548bec583f27093ab78d5d14.zip
Merge branch 'master' into bug230854
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT Custom Widgets')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java5
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DefaultContent.java6
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ST.java84
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java286
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java24
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java115
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TreeCursor.java963
8 files changed, 1240 insertions, 251 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java
index 49cae17511..10c005e006 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CCombo.java
@@ -162,6 +162,14 @@ public CCombo (Composite parent, int style) {
for (int i=0; i<arrowEvents.length; i++) arrow.addListener (arrowEvents [i], listener);
createPopup(null, -1);
+ if ((style & SWT.SIMPLE) == 0) {
+ int itemHeight = list.getItemHeight ();
+ if (itemHeight != 0) {
+ int maxHeight = getMonitor().getClientArea().height / 3;
+ visibleItemCount = Math.max(visibleItemCount, maxHeight / itemHeight);
+ }
+ }
+
initAccessible();
}
static int checkStyle (int style) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
index f9f31b7a0c..27413a2f50 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
@@ -1034,12 +1034,12 @@ void initAccessible() {
if (text != null) {
char mnemonic = _findMnemonic(text);
if (mnemonic != '\0') {
- shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
+ shortcut = SWT.getMessage ("SWT_Page_Mnemonic", new Object[] {new Character(mnemonic)}); //$NON-NLS-1$
}
}
}
if (childID == ACC.CHILDID_SELF) {
- shortcut = "Ctrl+PageDown"; //$NON-NLS-1$
+ shortcut = SWT.getMessage ("SWT_SwitchPage_Shortcut"); //$NON-NLS-1$
}
e.result = shortcut;
}
@@ -1064,6 +1064,7 @@ void initAccessible() {
childID = items.length + MAXIMIZE_CHILD_ID;
} else {
Rectangle location = getBounds();
+ location.x = location.y = 0;
location.height = location.height - getClientArea().height;
if (location.contains(testPoint)) {
childID = ACC.CHILDID_SELF;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DefaultContent.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DefaultContent.java
index cd00023a27..d95bb65698 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DefaultContent.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DefaultContent.java
@@ -769,7 +769,7 @@ public void replaceTextRange(int start, int replaceLength, String newText){
// inform listeners
StyledTextEvent event = new StyledTextEvent(this);
- event.type = StyledText.TextChanging;
+ event.type = ST.TextChanging;
event.start = start;
event.replaceLineCount = lineCount(start, replaceLength);
event.text = newText;
@@ -784,7 +784,7 @@ public void replaceTextRange(int start, int replaceLength, String newText){
insert(start, newText);
// inform listeners
event = new StyledTextEvent(this);
- event.type = StyledText.TextChanged;
+ event.type = ST.TextChanged;
sendTextEvent(event);
}
/**
@@ -809,7 +809,7 @@ public void setText (String text){
expandExp = 1;
indexLines();
StyledTextEvent event = new StyledTextEvent(this);
- event.type = StyledText.TextSet;
+ event.type = ST.TextSet;
event.text = "";
sendTextEvent(event);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ST.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ST.java
index 77276975cc..771fcf8017 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ST.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/ST.java
@@ -136,5 +136,89 @@ public class ST {
* @since 3.2
*/
public static final int BULLET_CUSTOM = 1 << 5;
+
+ /**
+ * The ExtendedModify event type (value is 3000).
+ *
+ * @since 3.8
+ */
+ public static final int ExtendedModify = 3000;
+
+ /**
+ * The LineGetBackground event type (value is 3001).
+ *
+ * @since 3.8
+ */
+ public static final int LineGetBackground = 3001;
+
+ /**
+ * The LineGetStyle event type (value is 3002).
+ *
+ * @since 3.8
+ */
+ public static final int LineGetStyle = 3002;
+
+ /**
+ * The TextChanging event type (value is 3003).
+ *
+ * @since 3.8
+ */
+ public static final int TextChanging = 3003;
+
+ /**
+ * The TextSet event type (value is 3004).
+ *
+ * @since 3.8
+ */
+ public static final int TextSet = 3004;
+
+ /**
+ * The VerifyKey event type (value is 3005).
+ *
+ * @since 3.8
+ */
+ public static final int VerifyKey = 3005;
+
+ /**
+ * The TextChanged event type (value is 3006).
+ *
+ * @since 3.8
+ */
+ public static final int TextChanged = 3006;
+
+ /**
+ * The LineGetSegments event type (value is 3007).
+ *
+ * @since 3.8
+ */
+ public static final int LineGetSegments = 3007;
+
+ /**
+ * The PaintObject event type (value is 3008).
+ *
+ * @since 3.8
+ */
+ public static final int PaintObject = 3008;
+
+ /**
+ * The WordNext event type (value is 3009).
+ *
+ * @since 3.8
+ */
+ public static final int WordNext = 3009;
+
+ /**
+ * The WordPrevious event type (value is 3010).
+ *
+ * @since 3.8
+ */
+ public static final int WordPrevious = 3010;
+
+ /**
+ * The CaretMoved event type (value is 3011).
+ *
+ * @since 3.8
+ */
+ public static final int CaretMoved = 3011;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index 250f2d7284..8001a64cdc 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -87,20 +87,6 @@ public class StyledText extends Canvas {
static final int DEFAULT_HEIGHT = 64;
static final int V_SCROLL_RATE = 50;
static final int H_SCROLL_RATE = 10;
-
- static final int ExtendedModify = 3000;
- static final int LineGetBackground = 3001;
- static final int LineGetStyle = 3002;
- static final int TextChanging = 3003;
- static final int TextSet = 3004;
- static final int VerifyKey = 3005;
- static final int TextChanged = 3006;
- static final int LineGetSegments = 3007;
- static final int PaintObject = 3008;
- static final int WordNext = 3009;
- static final int WordPrevious = 3010;
- static final int CaretMoved = 3011;
-
static final int PREVIOUS_OFFSET_TRAILING = 0;
static final int OFFSET_LEADING = 1;
@@ -112,6 +98,8 @@ public class StyledText extends Canvas {
TextChangeListener textChangeListener; // listener for TextChanging, TextChanged and TextSet events from StyledTextContent
int verticalScrollOffset = 0; // pixel based
int horizontalScrollOffset = 0; // pixel based
+ boolean alwaysShowScroll = true;
+ int ignoreResize = 0;
int topIndex = 0; // top visible line
int topIndexY;
int clientAreaHeight = 0; // the client area height. Needed to calculate content width for new visible lines during Resize callback
@@ -259,7 +247,7 @@ public class StyledText extends Canvas {
fontData = styledText.getFont().getFontData()[0];
tabLength = styledText.tabLength;
int lineCount = printerRenderer.lineCount;
- if (styledText.isListening(LineGetBackground) || (styledText.isBidi() && styledText.isListening(LineGetSegments)) || styledText.isListening(LineGetStyle)) {
+ if (styledText.isListening(ST.LineGetBackground) || (styledText.isBidi() && styledText.isListening(ST.LineGetSegments)) || styledText.isListening(ST.LineGetStyle)) {
StyledTextContent content = printerRenderer.content;
for (int i = 0; i < lineCount; i++) {
String line = content.getLine(i);
@@ -1295,7 +1283,7 @@ public void addExtendedModifyListener(ExtendedModifyListener extendedModifyListe
checkWidget();
if (extendedModifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
StyledTextListener typedListener = new StyledTextListener(extendedModifyListener);
- addListener(ExtendedModify, typedListener);
+ addListener(ST.ExtendedModify, typedListener);
}
/**
* Adds a bidirectional segment listener.
@@ -1325,7 +1313,7 @@ public void addExtendedModifyListener(ExtendedModifyListener extendedModifyListe
public void addBidiSegmentListener(BidiSegmentListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- addListener(LineGetSegments, new StyledTextListener(listener));
+ addListener(ST.LineGetSegments, new StyledTextListener(listener));
}
/**
* Adds a caret listener. CaretEvent is sent when the caret offset changes.
@@ -1344,7 +1332,7 @@ public void addBidiSegmentListener(BidiSegmentListener listener) {
public void addCaretListener(CaretListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- addListener(CaretMoved, new StyledTextListener(listener));
+ addListener(ST.CaretMoved, new StyledTextListener(listener));
}
/**
* Adds a line background listener. A LineGetBackground event is sent by the
@@ -1362,10 +1350,10 @@ public void addCaretListener(CaretListener listener) {
public void addLineBackgroundListener(LineBackgroundListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (!isListening(LineGetBackground)) {
+ if (!isListening(ST.LineGetBackground)) {
renderer.clearLineBackground(0, content.getLineCount());
}
- addListener(LineGetBackground, new StyledTextListener(listener));
+ addListener(ST.LineGetBackground, new StyledTextListener(listener));
}
/**
* Adds a line style listener. A LineGetStyle event is sent by the widget to
@@ -1383,11 +1371,11 @@ public void addLineBackgroundListener(LineBackgroundListener listener) {
public void addLineStyleListener(LineStyleListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (!isListening(LineGetStyle)) {
+ if (!isListening(ST.LineGetStyle)) {
setStyleRanges(0, 0, null, null, true);
renderer.clearLineStyle(0, content.getLineCount());
}
- addListener(LineGetStyle, new StyledTextListener(listener));
+ addListener(ST.LineGetStyle, new StyledTextListener(listener));
setCaretLocation();
}
/**
@@ -1429,7 +1417,7 @@ public void addModifyListener(ModifyListener modifyListener) {
public void addPaintObjectListener(PaintObjectListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- addListener(PaintObject, new StyledTextListener(listener));
+ addListener(ST.PaintObject, new StyledTextListener(listener));
}
/**
* Adds a selection listener. A Selection event is sent by the widget when the
@@ -1476,7 +1464,7 @@ public void addSelectionListener(SelectionListener listener) {
public void addVerifyKeyListener(VerifyKeyListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- addListener(VerifyKey, new StyledTextListener(listener));
+ addListener(ST.VerifyKey, new StyledTextListener(listener));
}
/**
* Adds a verify listener. A Verify event is sent by the widget when the widget text
@@ -1521,8 +1509,8 @@ public void addVerifyListener(VerifyListener verifyListener) {
public void addWordMovementListener(MovementListener movementListener) {
checkWidget();
if (movementListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- addListener(WordNext, new StyledTextListener(movementListener));
- addListener(WordPrevious, new StyledTextListener(movementListener));
+ addListener(ST.WordNext, new StyledTextListener(movementListener));
+ addListener(ST.WordPrevious, new StyledTextListener(movementListener));
}
/**
* Appends a string to the text at the end of the widget.
@@ -1627,8 +1615,11 @@ void calculateTopIndex(int delta) {
}
}
if (topIndex != oldTopIndex || oldTopIndexY != topIndexY) {
+ int width = renderer.getWidth();
renderer.calculateClientArea();
- setScrollBars(false);
+ if (width != renderer.getWidth()) {
+ setScrollBars(false);
+ }
}
}
/**
@@ -1835,6 +1826,26 @@ public int getAlignment() {
checkWidget();
return alignment;
}
+/**
+ * Returns the Always Show Scrollbars flag. True if the scrollbars are
+ * always shown even if they are not required. False if the scrollbars are only
+ * visible when some part of the content needs to be scrolled to be seen.
+ * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the
+ * horizontal and vertical directions.
+ *
+ * @return the Always Show Scrollbars flag value
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.8
+ */
+public boolean getAlwaysShowScrollBars() {
+ checkWidget();
+ return alwaysShowScroll;
+}
int getAvailableHeightAbove(int height) {
int maxHeight = verticalScrollOffset;
if (maxHeight == -1) {
@@ -3936,7 +3947,7 @@ public Color getLineBackground(int index) {
if (index < 0 || index > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- return isListening(LineGetBackground) ? null : renderer.getLineBackground(index, null);
+ return isListening(ST.LineGetBackground) ? null : renderer.getLineBackground(index, null);
}
/**
* Returns the bullet of the line at the given index.
@@ -3960,7 +3971,7 @@ public Bullet getLineBullet(int index) {
if (index < 0 || index > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- return isListening(LineGetStyle) ? null : renderer.getLineBullet(index, null);
+ return isListening(ST.LineGetStyle) ? null : renderer.getLineBullet(index, null);
}
/**
* Returns the line background data for the given line or null if
@@ -3972,7 +3983,7 @@ public Bullet getLineBullet(int index) {
* @return line background data for the given line.
*/
StyledTextEvent getLineBackgroundData(int lineOffset, String line) {
- return sendLineEvent(LineGetBackground, lineOffset, line);
+ return sendLineEvent(ST.LineGetBackground, lineOffset, line);
}
/**
* Gets the number of text lines.
@@ -4091,7 +4102,7 @@ public int getLineIndent(int index) {
if (index < 0 || index > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- return isListening(LineGetStyle) ? 0 : renderer.getLineIndent(index, indent);
+ return isListening(ST.LineGetStyle) ? 0 : renderer.getLineIndent(index, indent);
}
/**
* Returns whether the line at the given index is justified.
@@ -4117,7 +4128,7 @@ public boolean getLineJustify(int index) {
if (index < 0 || index > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- return isListening(LineGetStyle) ? false : renderer.getLineJustify(index, justify);
+ return isListening(ST.LineGetStyle) ? false : renderer.getLineJustify(index, justify);
}
/**
* Returns the line spacing of the widget.
@@ -4151,7 +4162,7 @@ public int getLineSpacing() {
* line start and end after line end
*/
StyledTextEvent getLineStyleData(int lineOffset, String line) {
- return sendLineEvent(LineGetStyle, lineOffset, line);
+ return sendLineEvent(ST.LineGetStyle, lineOffset, line);
}
/**
* Returns the top pixel, relative to the client area, of a given line.
@@ -4246,7 +4257,7 @@ public int[] getLineTabStops(int index) {
if (index < 0 || index > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- if (isListening(LineGetStyle)) return null;
+ if (isListening(ST.LineGetStyle)) return null;
int[] tabs = renderer.getLineTabStops(index, null);
if (tabs == null) tabs = this.tabs;
if (tabs == null) return new int [] {renderer.tabWidth};
@@ -4278,7 +4289,7 @@ public int getLineWrapIndent(int index) {
if (index < 0 || index > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- return isListening(LineGetStyle) ? 0 : renderer.getLineWrapIndent(index, wrapIndent);
+ return isListening(ST.LineGetStyle) ? 0 : renderer.getLineWrapIndent(index, wrapIndent);
}
/**
* Returns the left margin.
@@ -4539,7 +4550,7 @@ String getPlatformDelimitedText(TextWriter writer) {
*/
public int[] getRanges() {
checkWidget();
- if (!isListening(LineGetStyle)) {
+ if (!isListening(ST.LineGetStyle)) {
int[] ranges = renderer.getRanges(0, content.getCharCount());
if (ranges != null) return ranges;
}
@@ -4581,7 +4592,7 @@ public int[] getRanges(int start, int length) {
if (start > end || start < 0 || end > contentLength) {
SWT.error(SWT.ERROR_INVALID_RANGE);
}
- if (!isListening(LineGetStyle)) {
+ if (!isListening(ST.LineGetStyle)) {
int[] ranges = renderer.getRanges(start, length);
if (ranges != null) return ranges;
}
@@ -4756,12 +4767,12 @@ public String getSelectionText() {
}
StyledTextEvent getBidiSegments(int lineOffset, String line) {
if (!isBidi()) return null;
- if (!isListening(LineGetSegments)) {
+ if (!isListening(ST.LineGetSegments)) {
StyledTextEvent event = new StyledTextEvent(content);
event.segments = getBidiSegmentsCompatibility(line, lineOffset);
return event;
}
- StyledTextEvent event = sendLineEvent(LineGetSegments, lineOffset, line);
+ StyledTextEvent event = sendLineEvent(ST.LineGetSegments, lineOffset, line);
if (event == null || event.segments == null || event.segments.length == 0) return null;
int lineLength = line.length();
int[] segments = event.segments;
@@ -4875,7 +4886,7 @@ public StyleRange getStyleRangeAtOffset(int offset) {
if (offset < 0 || offset >= getCharCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
- if (!isListening(LineGetStyle)) {
+ if (!isListening(ST.LineGetStyle)) {
StyleRange[] ranges = renderer.getStyleRanges(offset, 1, true);
if (ranges != null) return ranges[0];
}
@@ -5022,7 +5033,7 @@ public StyleRange[] getStyleRanges(int start, int length, boolean includeRanges)
if (start > end || start < 0 || end > contentLength) {
SWT.error(SWT.ERROR_INVALID_RANGE);
}
- if (!isListening(LineGetStyle)) {
+ if (!isListening(ST.LineGetStyle)) {
StyleRange[] ranges = renderer.getStyleRanges(start, length, includeRanges);
if (ranges != null) return ranges;
}
@@ -5336,7 +5347,7 @@ int getWordNext (int offset, int movement, boolean ignoreListener) {
}
}
if (ignoreListener) return newOffset;
- return sendWordBoundaryEvent(WordNext, movement, offset, newOffset, lineText, lineOffset);
+ return sendWordBoundaryEvent(ST.WordNext, movement, offset, newOffset, lineText, lineOffset);
}
int getWordPrevious(int offset, int movement) {
return getWordPrevious(offset, movement, false);
@@ -5365,7 +5376,7 @@ int getWordPrevious(int offset, int movement, boolean ignoreListener) {
}
}
if (ignoreListener) return newOffset;
- return sendWordBoundaryEvent(WordPrevious, movement, offset, newOffset, lineText, lineOffset);
+ return sendWordBoundaryEvent(ST.WordPrevious, movement, offset, newOffset, lineText, lineOffset);
}
/**
* Returns whether the widget wraps lines.
@@ -5933,7 +5944,7 @@ void handleKeyDown(Event event) {
verifyEvent.keyLocation = event.keyLocation;
verifyEvent.stateMask = event.stateMask;
verifyEvent.doit = true;
- notifyListeners(VerifyKey, verifyEvent);
+ notifyListeners(ST.VerifyKey, verifyEvent);
if (verifyEvent.doit) {
if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL && event.keyCode == SWT.SHIFT && isBidiCaret()) {
newOrientation = event.keyLocation == SWT.LEFT ? SWT.LEFT_TO_RIGHT : SWT.RIGHT_TO_LEFT;
@@ -6119,19 +6130,9 @@ void handleResize(Event event) {
Rectangle clientArea = getClientArea();
clientAreaHeight = clientArea.height;
clientAreaWidth = clientArea.width;
- /* Redraw the old or new right/bottom margin if needed */
- if (oldWidth != clientAreaWidth) {
- if (rightMargin > 0) {
- int x = (oldWidth < clientAreaWidth ? oldWidth : clientAreaWidth) - rightMargin;
- super.redraw(x, 0, rightMargin, oldHeight, false);
- }
- }
- if (oldHeight != clientAreaHeight) {
- if (bottomMargin > 0) {
- int y = (oldHeight < clientAreaHeight ? oldHeight : clientAreaHeight) - bottomMargin;
- super.redraw(0, y, oldWidth, bottomMargin, false);
- }
- }
+ if (!alwaysShowScroll && ignoreResize != 0) return;
+
+ redrawMargins(oldHeight, oldWidth);
if (wordWrap) {
if (oldWidth != clientAreaWidth) {
renderer.reset(0, content.getLineCount());
@@ -6708,7 +6709,7 @@ void initializeAccessible() {
public void getTextAttributes(AccessibleTextAttributeEvent e) {
StyledText st = StyledText.this;
int contentLength = st.getCharCount();
- if (!isListening(LineGetStyle) && st.renderer.styleCount == 0) {
+ if (!isListening(ST.LineGetStyle) && st.renderer.styleCount == 0) {
e.start = 0;
e.end = contentLength;
e.textStyle = new TextStyle(st.getFont(), st.foreground, st.background);
@@ -7149,7 +7150,7 @@ void modifyContent(Event event, boolean updateCaret) {
if (event.doit) {
StyledTextEvent styledTextEvent = null;
int replacedLength = event.end - event.start;
- if (isListening(ExtendedModify)) {
+ if (isListening(ST.ExtendedModify)) {
styledTextEvent = new StyledTextEvent(content);
styledTextEvent.start = event.start;
styledTextEvent.end = event.start + event.text.length();
@@ -7186,13 +7187,13 @@ void modifyContent(Event event, boolean updateCaret) {
showCaret();
}
notifyListeners(SWT.Modify, event);
- if (isListening(ExtendedModify)) {
- notifyListeners(ExtendedModify, styledTextEvent);
+ if (isListening(ST.ExtendedModify)) {
+ notifyListeners(ST.ExtendedModify, styledTextEvent);
}
}
}
void paintObject(GC gc, int x, int y, int ascent, int descent, StyleRange style, Bullet bullet, int bulletIndex) {
- if (isListening(PaintObject)) {
+ if (isListening(ST.PaintObject)) {
StyledTextEvent event = new StyledTextEvent (content) ;
event.gc = gc;
event.x = x;
@@ -7202,7 +7203,7 @@ void paintObject(GC gc, int x, int y, int ascent, int descent, StyleRange style,
event.style = style;
event.bullet = bullet;
event.bulletIndex = bulletIndex;
- notifyListeners(PaintObject, event);
+ notifyListeners(ST.PaintObject, event);
}
}
/**
@@ -7420,6 +7421,21 @@ void redrawLinesBullet (int[] redrawLines) {
super.redraw(0, y, width, height, false);
}
}
+void redrawMargins(int oldHeight, int oldWidth) {
+ /* Redraw the old or new right/bottom margin if needed */
+ if (oldWidth != clientAreaWidth) {
+ if (rightMargin > 0) {
+ int x = (oldWidth < clientAreaWidth ? oldWidth : clientAreaWidth) - rightMargin;
+ super.redraw(x, 0, rightMargin, oldHeight, false);
+ }
+ }
+ if (oldHeight != clientAreaHeight) {
+ if (bottomMargin > 0) {
+ int y = (oldHeight < clientAreaHeight ? oldHeight : clientAreaHeight) - bottomMargin;
+ super.redraw(0, y, oldWidth, bottomMargin, false);
+ }
+ }
+}
/**
* Redraws the specified text range.
*
@@ -7475,7 +7491,7 @@ public void redrawRange(int start, int length, boolean clearBackground) {
public void removeBidiSegmentListener(BidiSegmentListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(LineGetSegments, listener);
+ removeListener(ST.LineGetSegments, listener);
}
/**
* Removes the specified caret listener.
@@ -7495,7 +7511,7 @@ public void removeBidiSegmentListener(BidiSegmentListener listener) {
public void removeCaretListener(CaretListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(CaretMoved, listener);
+ removeListener(ST.CaretMoved, listener);
}
/**
* Removes the specified extended modify listener.
@@ -7513,7 +7529,7 @@ public void removeCaretListener(CaretListener listener) {
public void removeExtendedModifyListener(ExtendedModifyListener extendedModifyListener) {
checkWidget();
if (extendedModifyListener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(ExtendedModify, extendedModifyListener);
+ removeListener(ST.ExtendedModify, extendedModifyListener);
}
/**
* Removes the specified line background listener.
@@ -7531,7 +7547,7 @@ public void removeExtendedModifyListener(ExtendedModifyListener extendedModifyLi
public void removeLineBackgroundListener(LineBackgroundListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(LineGetBackground, listener);
+ removeListener(ST.LineGetBackground, listener);
}
/**
* Removes the specified line style listener.
@@ -7549,7 +7565,7 @@ public void removeLineBackgroundListener(LineBackgroundListener listener) {
public void removeLineStyleListener(LineStyleListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(LineGetStyle, listener);
+ removeListener(ST.LineGetStyle, listener);
setCaretLocation();
}
/**
@@ -7587,7 +7603,7 @@ public void removeModifyListener(ModifyListener modifyListener) {
public void removePaintObjectListener(PaintObjectListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(PaintObject, listener);
+ removeListener(ST.PaintObject, listener);
}
/**
* Removes the listener from the collection of listeners who will
@@ -7644,7 +7660,7 @@ public void removeVerifyListener(VerifyListener verifyListener) {
*/
public void removeVerifyKeyListener(VerifyKeyListener listener) {
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(VerifyKey, listener);
+ removeListener(ST.VerifyKey, listener);
}
/**
* Removes the specified word movement listener.
@@ -7669,8 +7685,8 @@ public void removeVerifyKeyListener(VerifyKeyListener listener) {
public void removeWordMovementListener(MovementListener listener) {
checkWidget();
if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- removeListener(WordNext, listener);
- removeListener(WordPrevious, listener);
+ removeListener(ST.WordNext, listener);
+ removeListener(ST.WordPrevious, listener);
}
/**
* Replaces the styles in the given range with new styles. This method
@@ -7708,7 +7724,7 @@ public void removeWordMovementListener(MovementListener listener) {
*/
public void replaceStyleRanges(int start, int length, StyleRange[] ranges) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (ranges == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
setStyleRanges(start, length, null, ranges, false);
}
@@ -8154,6 +8170,28 @@ public void setAlignment(int alignment) {
super.redraw();
}
/**
+ * Set the Always Show Scrollbars flag. True if the scrollbars are
+ * always shown even if they are not required. False if the scrollbars are only
+ * visible when some part of the content needs to be scrolled to be seen.
+ * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the
+ * horizontal and vertical directions.
+ *
+ * @param show true to show the scrollbars even when not required, false to show scrollbars only when required
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.8
+ */
+public void setAlwaysShowScrollBars(boolean show) {
+ checkWidget();
+ if (show == alwaysShowScroll) return;
+ alwaysShowScroll = show;
+ setScrollBars(true);
+}
+/**
* @see Control#setBackground(Color)
*/
public void setBackground(Color color) {
@@ -8448,10 +8486,10 @@ public void setCaretOffset(int offset) {
void setCaretOffset(int offset, int alignment) {
if (caretOffset != offset) {
caretOffset = offset;
- if (isListening(CaretMoved)) {
+ if (isListening(ST.CaretMoved)) {
StyledTextEvent event = new StyledTextEvent(content);
event.end = caretOffset;
- notifyListeners(CaretMoved, event);
+ notifyListeners(ST.CaretMoved, event);
}
}
if (alignment != SWT.DEFAULT) {
@@ -8834,7 +8872,7 @@ public void setLeftMargin (int leftMargin) {
*/
public void setLineAlignment(int startLine, int lineCount, int alignment) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -8885,7 +8923,7 @@ public void setLineAlignment(int startLine, int lineCount, int alignment) {
*/
public void setLineBackground(int startLine, int lineCount, Color background) {
checkWidget();
- if (isListening(LineGetBackground)) return;
+ if (isListening(ST.LineGetBackground)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -8930,7 +8968,7 @@ public void setLineBackground(int startLine, int lineCount, Color background) {
*/
public void setLineBullet(int startLine, int lineCount, Bullet bullet) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -8984,7 +9022,7 @@ void setVariableLineHeight () {
*/
public void setLineIndent(int startLine, int lineCount, int indent) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -9033,7 +9071,7 @@ public void setLineIndent(int startLine, int lineCount, int indent) {
*/
public void setLineJustify(int startLine, int lineCount, boolean justify) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -9100,7 +9138,7 @@ public void setLineSpacing(int lineSpacing) {
*/
public void setLineTabStops(int startLine, int lineCount, int[] tabStops) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -9157,7 +9195,7 @@ public void setLineTabStops(int startLine, int lineCount, int[] tabStops) {
*/
public void setLineWrapIndent(int startLine, int lineCount, int wrapIndent) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (startLine < 0 || startLine + lineCount > content.getLineCount()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
@@ -9271,6 +9309,17 @@ public void setRightMargin (int rightMargin) {
checkWidget();
setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
}
+void setScrollBar(ScrollBar bar, int clientArea, int maximum, int margin) {
+ int inactive = 1;
+ if (clientArea < maximum) {
+ bar.setMaximum(maximum - margin);
+ bar.setThumb(clientArea - margin);
+ bar.setPageIncrement(clientArea - margin);
+ if (!alwaysShowScroll) bar.setVisible(true);
+ } else if (bar.getThumb() != inactive || bar.getMaximum() != inactive) {
+ bar.setValues(bar.getSelection(), bar.getMinimum(), inactive, inactive, bar.getIncrement(), inactive);
+ }
+}
/**
* Adjusts the maximum and the page size of the scroll bars to
* reflect content width/length changes.
@@ -9278,49 +9327,32 @@ public void setRightMargin (int rightMargin) {
* @param vertical indicates if the vertical scrollbar also needs to be set
*/
void setScrollBars(boolean vertical) {
- int inactive = 1;
- if (vertical || !isFixedLineHeight()) {
- ScrollBar verticalBar = getVerticalBar();
- if (verticalBar != null) {
- int maximum = renderer.getHeight();
- // only set the real values if the scroll bar can be used
- // (ie. because the thumb size is less than the scroll maximum)
- // avoids flashing on Motif, fixes 1G7RE1J and 1G5SE92
- if (clientAreaHeight < maximum) {
- verticalBar.setMaximum(maximum - topMargin - bottomMargin);
- verticalBar.setThumb(clientAreaHeight - topMargin - bottomMargin);
- verticalBar.setPageIncrement(clientAreaHeight - topMargin - bottomMargin);
- } else if (verticalBar.getThumb() != inactive || verticalBar.getMaximum() != inactive) {
- verticalBar.setValues(
- verticalBar.getSelection(),
- verticalBar.getMinimum(),
- inactive,
- inactive,
- verticalBar.getIncrement(),
- inactive);
+ ignoreResize++;
+ if (!isFixedLineHeight() || !alwaysShowScroll) vertical = true;
+ ScrollBar verticalBar = vertical ? getVerticalBar() : null;
+ ScrollBar horizontalBar = getHorizontalBar();
+ int oldHeight = clientAreaHeight;
+ int oldWidth = clientAreaWidth;
+ if (!alwaysShowScroll) {
+ if (verticalBar != null) verticalBar.setVisible(false);
+ if (horizontalBar != null) horizontalBar.setVisible(false);
+ }
+ if (verticalBar != null) {
+ setScrollBar(verticalBar, clientAreaHeight, renderer.getHeight(), topMargin + bottomMargin);
+ }
+ if (horizontalBar != null) {
+ setScrollBar(horizontalBar, clientAreaWidth, renderer.getWidth(), leftMargin + rightMargin);
+ if (!alwaysShowScroll && horizontalBar.getVisible() && verticalBar != null) {
+ setScrollBar(verticalBar, clientAreaHeight, renderer.getHeight(), topMargin + bottomMargin);
+ if (verticalBar.getVisible()) {
+ setScrollBar(horizontalBar, clientAreaWidth, renderer.getWidth(), leftMargin + rightMargin);
}
}
}
- ScrollBar horizontalBar = getHorizontalBar();
- if (horizontalBar != null && horizontalBar.getVisible()) {
- int maximum = renderer.getWidth();
- // only set the real values if the scroll bar can be used
- // (ie. because the thumb size is less than the scroll maximum)
- // avoids flashing on Motif, fixes 1G7RE1J and 1G5SE92
- if (clientAreaWidth < maximum) {
- horizontalBar.setMaximum(maximum - leftMargin - rightMargin);
- horizontalBar.setThumb(clientAreaWidth - leftMargin - rightMargin);
- horizontalBar.setPageIncrement(clientAreaWidth - leftMargin - rightMargin);
- } else if (horizontalBar.getThumb() != inactive || horizontalBar.getMaximum() != inactive) {
- horizontalBar.setValues(
- horizontalBar.getSelection(),
- horizontalBar.getMinimum(),
- inactive,
- inactive,
- horizontalBar.getIncrement(),
- inactive);
- }
+ if (!alwaysShowScroll) {
+ redrawMargins(oldHeight, oldWidth);
}
+ ignoreResize--;
}
/**
* Sets the selection to the given position and scrolls it into view. Equivalent to setSelection(start,start).
@@ -9553,7 +9585,7 @@ public void setSelectionRange(int start, int length) {
*/
public void setStyleRange(StyleRange range) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (range != null) {
if (range.isUnstyled()) {
setStyleRanges(range.start, range.length, null, null, false);
@@ -9601,7 +9633,7 @@ public void setStyleRange(StyleRange range) {
*/
public void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (ranges == null || styles == null) {
setStyleRanges(start, length, null, null, false);
} else {
@@ -9643,7 +9675,7 @@ public void setStyleRanges(int start, int length, int[] ranges, StyleRange[] sty
*/
public void setStyleRanges(int[] ranges, StyleRange[] styles) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (ranges == null || styles == null) {
setStyleRanges(0, 0, null, null, true);
} else {
@@ -9769,7 +9801,7 @@ void setStyleRanges(int start, int length, int[] ranges, StyleRange[] styles, bo
*/
public void setStyleRanges(StyleRange[] ranges) {
checkWidget();
- if (isListening(LineGetStyle)) return;
+ if (isListening(ST.LineGetStyle)) return;
if (ranges == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
setStyleRanges(0, 0, null, ranges, true);
}
@@ -9865,7 +9897,7 @@ public void setText(String text) {
notifyListeners(SWT.Verify, event);
if (event.doit) {
StyledTextEvent styledTextEvent = null;
- if (isListening(ExtendedModify)) {
+ if (isListening(ST.ExtendedModify)) {
styledTextEvent = new StyledTextEvent(content);
styledTextEvent.start = event.start;
styledTextEvent.end = event.start + event.text.length();
@@ -9874,7 +9906,7 @@ public void setText(String text) {
content.setText(event.text);
notifyListeners(SWT.Modify, event);
if (styledTextEvent != null) {
- notifyListeners(ExtendedModify, styledTextEvent);
+ notifyListeners(ST.ExtendedModify, styledTextEvent);
}
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java
index d9f026b5dd..3403000c55 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java
@@ -28,22 +28,22 @@ StyledTextListener(SWTEventListener listener) {
public void handleEvent(Event e) {
switch (e.type) {
- case StyledText.ExtendedModify:
+ case ST.ExtendedModify:
ExtendedModifyEvent extendedModifyEvent = new ExtendedModifyEvent((StyledTextEvent) e);
((ExtendedModifyListener) eventListener).modifyText(extendedModifyEvent);
break;
- case StyledText.LineGetBackground:
+ case ST.LineGetBackground:
LineBackgroundEvent lineBgEvent = new LineBackgroundEvent((StyledTextEvent) e);
((LineBackgroundListener) eventListener).lineGetBackground(lineBgEvent);
((StyledTextEvent) e).lineBackground = lineBgEvent.lineBackground;
break;
- case StyledText.LineGetSegments:
+ case ST.LineGetSegments:
BidiSegmentEvent segmentEvent = new BidiSegmentEvent((StyledTextEvent) e);
((BidiSegmentListener) eventListener).lineGetSegments(segmentEvent);
((StyledTextEvent) e).segments = segmentEvent.segments;
((StyledTextEvent) e).segmentsChars = segmentEvent.segmentsChars;
break;
- case StyledText.LineGetStyle:
+ case ST.LineGetStyle:
LineStyleEvent lineStyleEvent = new LineStyleEvent((StyledTextEvent) e);
((LineStyleListener) eventListener).lineGetStyle(lineStyleEvent);
((StyledTextEvent) e).ranges = lineStyleEvent.ranges;
@@ -56,42 +56,42 @@ public void handleEvent(Event e) {
((StyledTextEvent) e).bulletIndex = lineStyleEvent.bulletIndex;
((StyledTextEvent) e).tabStops = lineStyleEvent.tabStops;
break;
- case StyledText.PaintObject:
+ case ST.PaintObject:
PaintObjectEvent paintObjectEvent = new PaintObjectEvent((StyledTextEvent) e);
((PaintObjectListener) eventListener).paintObject(paintObjectEvent);
break;
- case StyledText.VerifyKey:
+ case ST.VerifyKey:
VerifyEvent verifyEvent = new VerifyEvent(e);
((VerifyKeyListener) eventListener).verifyKey(verifyEvent);
e.doit = verifyEvent.doit;
break;
- case StyledText.TextChanged: {
+ case ST.TextChanged: {
TextChangedEvent textChangedEvent = new TextChangedEvent((StyledTextContent) e.data);
((TextChangeListener) eventListener).textChanged(textChangedEvent);
break;
}
- case StyledText.TextChanging:
+ case ST.TextChanging:
TextChangingEvent textChangingEvent = new TextChangingEvent((StyledTextContent) e.data, (StyledTextEvent) e);
((TextChangeListener) eventListener).textChanging(textChangingEvent);
break;
- case StyledText.TextSet: {
+ case ST.TextSet: {
TextChangedEvent textChangedEvent = new TextChangedEvent((StyledTextContent) e.data);
((TextChangeListener) eventListener).textSet(textChangedEvent);
break;
}
- case StyledText.WordNext: {
+ case ST.WordNext: {
MovementEvent wordBoundaryEvent = new MovementEvent((StyledTextEvent) e);
((MovementListener) eventListener).getNextOffset(wordBoundaryEvent);
((StyledTextEvent) e).end = wordBoundaryEvent.newOffset;
break;
}
- case StyledText.WordPrevious: {
+ case ST.WordPrevious: {
MovementEvent wordBoundaryEvent = new MovementEvent((StyledTextEvent) e);
((MovementListener) eventListener).getPreviousOffset(wordBoundaryEvent);
((StyledTextEvent) e).end = wordBoundaryEvent.newOffset;
break;
}
- case StyledText.CaretMoved: {
+ case ST.CaretMoved: {
CaretEvent caretEvent = new CaretEvent((StyledTextEvent) e);
((CaretListener) eventListener).caretMoved(caretEvent);
((StyledTextEvent) e).end = caretEvent.caretOffset;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java
index 0408aa5fd7..a597b782e5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableCursor.java
@@ -20,108 +20,9 @@ import org.eclipse.swt.events.*;
* A TableCursor provides a way for the user to navigate around a Table
* using the keyboard. It also provides a mechanism for selecting an
* individual cell in a table.
- *
- * <p> Here is an example of using a TableCursor to navigate to a cell and then edit it.
- *
- * <code><pre>
- * public static void main(String[] args) {
- * Display display = new Display();
- * Shell shell = new Shell(display);
- * shell.setLayout(new GridLayout());
- *
- * // create a a table with 3 columns and fill with data
- * final Table table = new Table(shell, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
- * table.setLayoutData(new GridData(GridData.FILL_BOTH));
- * TableColumn column1 = new TableColumn(table, SWT.NONE);
- * TableColumn column2 = new TableColumn(table, SWT.NONE);
- * TableColumn column3 = new TableColumn(table, SWT.NONE);
- * for (int i = 0; i &lt; 100; i++) {
- * TableItem item = new TableItem(table, SWT.NONE);
- * item.setText(new String[] { "cell "+i+" 0", "cell "+i+" 1", "cell "+i+" 2"});
- * }
- * column1.pack();
- * column2.pack();
- * column3.pack();
- *
- * // create a TableCursor to navigate around the table
- * final TableCursor cursor = new TableCursor(table, SWT.NONE);
- * // create an editor to edit the cell when the user hits "ENTER"
- * // while over a cell in the table
- * final ControlEditor editor = new ControlEditor(cursor);
- * editor.grabHorizontal = true;
- * editor.grabVertical = true;
- *
- * cursor.addSelectionListener(new SelectionAdapter() {
- * // when the TableEditor is over a cell, select the corresponding row in
- * // the table
- * public void widgetSelected(SelectionEvent e) {
- * table.setSelection(new TableItem[] {cursor.getRow()});
- * }
- * // when the user hits "ENTER" in the TableCursor, pop up a text editor so that
- * // they can change the text of the cell
- * public void widgetDefaultSelected(SelectionEvent e){
- * final Text text = new Text(cursor, SWT.NONE);
- * TableItem row = cursor.getRow();
- * int column = cursor.getColumn();
- * text.setText(row.getText(column));
- * text.addKeyListener(new KeyAdapter() {
- * public void keyPressed(KeyEvent e) {
- * // close the text editor and copy the data over
- * // when the user hits "ENTER"
- * if (e.character == SWT.CR) {
- * TableItem row = cursor.getRow();
- * int column = cursor.getColumn();
- * row.setText(column, text.getText());
- * text.dispose();
- * }
- * // close the text editor when the user hits "ESC"
- * if (e.character == SWT.ESC) {
- * text.dispose();
- * }
- * }
- * });
- * editor.setEditor(text);
- * text.setFocus();
- * }
- * });
- * // Hide the TableCursor when the user hits the "MOD1" or "MOD2" key.
- * // This allows the user to select multiple items in the table.
- * cursor.addKeyListener(new KeyAdapter() {
- * public void keyPressed(KeyEvent e) {
- * if (e.keyCode == SWT.MOD1 ||
- * e.keyCode == SWT.MOD2 ||
- * (e.stateMask & SWT.MOD1) != 0 ||
- * (e.stateMask & SWT.MOD2) != 0) {
- * cursor.setVisible(false);
- * }
- * }
- * });
- * // Show the TableCursor when the user releases the "MOD2" or "MOD1" key.
- * // This signals the end of the multiple selection task.
- * table.addKeyListener(new KeyAdapter() {
- * public void keyReleased(KeyEvent e) {
- * if (e.keyCode == SWT.MOD1 && (e.stateMask & SWT.MOD2) != 0) return;
- * if (e.keyCode == SWT.MOD2 && (e.stateMask & SWT.MOD1) != 0) return;
- * if (e.keyCode != SWT.MOD1 && (e.stateMask & SWT.MOD1) != 0) return;
- * if (e.keyCode != SWT.MOD2 && (e.stateMask & SWT.MOD2) != 0) return;
- *
- * TableItem[] selection = table.getSelection();
- * TableItem row = (selection.length == 0) ? table.getItem(table.getTopIndex()) : selection[0];
- * table.showItem(row);
- * cursor.setSelection(row, 0);
- * cursor.setVisible(true);
- * cursor.setFocus();
- * }
- * });
- *
- * shell.open();
- * while (!shell.isDisposed()) {
- * if (!display.readAndDispatch())
- * display.sleep();
- * }
- * display.dispose();
- * }
- * </pre></code>
+ * <p>
+ * For a detailed example of using a TableCursor to navigate to a cell and then edit it see
+ * http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet96.java .
*
* <dl>
* <dt><b>Styles:</b></dt>
@@ -144,7 +45,7 @@ public class TableCursor extends Canvas {
Color background = null;
Color foreground = null;
- // By default, invert the list selection colors
+ /* By default, invert the list selection colors */
static final int BACKGROUND = SWT.COLOR_LIST_SELECTION_TEXT;
static final int FOREGROUND = SWT.COLOR_LIST_SELECTION;
@@ -414,7 +315,6 @@ void paint(Event event) {
if (row == null) return;
int columnIndex = column == null ? 0 : table.indexOf(column);
GC gc = event.gc;
- Display display = getDisplay();
gc.setBackground(getBackground());
gc.setForeground(getForeground());
gc.fillRectangle(event.x, event.y, event.width, event.height);
@@ -472,6 +372,7 @@ void paint(Event event) {
gc.drawString(text, x, textY);
}
if (isFocusControl()) {
+ Display display = getDisplay();
gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawFocus(0, 0, size.x, size.y);
@@ -621,9 +522,9 @@ void _resize() {
}
}
/**
- * Returns the column over which the TableCursor is positioned.
+ * Returns the index of the column over which the TableCursor is positioned.
*
- * @return the column for the current position
+ * @return the column index for the current position
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
@@ -661,7 +562,7 @@ public Color getForeground() {
/**
* Returns the row over which the TableCursor is positioned.
*
- * @return the item for the current position
+ * @return the item for the current position, or <code>null</code> if none
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TreeCursor.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TreeCursor.java
new file mode 100644
index 0000000000..a15f4041c9
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TreeCursor.java
@@ -0,0 +1,963 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.custom;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.accessibility.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * A TreeCursor provides a way for the user to navigate around a Tree with columns using the
+ * keyboard. It also provides a mechanism for selecting an individual cell in a tree.
+ * <p>
+ * For a detailed example of using a TreeCursor to navigate to a cell and then edit it see
+ * http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet360.java .
+ *
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>BORDER</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection, DefaultSelection</dd>
+ * </dl>
+ *
+ * @since 3.8
+ */
+public class TreeCursor extends Canvas {
+ Tree tree;
+ TreeItem row;
+ TreeColumn column;
+ Listener listener, treeListener, resizeListener, disposeItemListener, disposeColumnListener;
+
+ Color background = null;
+ Color foreground = null;
+
+ /* By default, invert the list selection colors */
+ static final int BACKGROUND = SWT.COLOR_LIST_SELECTION_TEXT;
+ static final int FOREGROUND = SWT.COLOR_LIST_SELECTION;
+
+/**
+ * Constructs a new instance of this class given its parent tree and a style value describing
+ * its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in class <code>SWT</code> which
+ * is applicable to instances of this class, or must be built by <em>bitwise OR</em>'ing
+ * together (that is, using the <code>int</code> "|" operator) two or more of those
+ * <code>SWT</code> style constants. The class description lists the style constants that are
+ * applicable to the class. Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a Tree control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see Widget#checkSubclass()
+ * @see Widget#getStyle()
+ */
+public TreeCursor(Tree parent, int style) {
+ super(parent, style);
+ tree = parent;
+ setBackground(null);
+ setForeground(null);
+
+ listener = new Listener() {
+ public void handleEvent(Event event) {
+ if (row != null) {
+ /*
+ * Detect cases where the cursor position has become invalid and fix it.
+ * The typical cause of this is programmatic tree changes, such as
+ * expanding/collapsing and item and creating/disposing items.
+ */
+ if (row.isDisposed()) {
+ unhookRowColumnListeners();
+ _resize();
+ tree.setFocus();
+ return;
+ }
+ TreeItem current = row;
+ TreeItem parentItem = row.getParentItem();
+ while (parentItem != null && !parentItem.getExpanded()) {
+ current = parentItem;
+ parentItem = current.getParentItem();
+ }
+ if (current != row) {
+ setRowColumn(current, column, false);
+ }
+ }
+ switch (event.type) {
+ case SWT.Dispose:
+ onDispose(event);
+ break;
+ case SWT.FocusIn:
+ case SWT.FocusOut:
+ redraw();
+ break;
+ case SWT.KeyDown:
+ keyDown(event);
+ break;
+ case SWT.Paint:
+ paint(event);
+ break;
+ case SWT.Traverse:
+ event.doit = true;
+ switch (event.detail) {
+ case SWT.TRAVERSE_ARROW_NEXT:
+ case SWT.TRAVERSE_ARROW_PREVIOUS:
+ case SWT.TRAVERSE_RETURN:
+ event.doit = false;
+ break;
+ }
+ break;
+ }
+ }
+ };
+ int[] events = new int[] { SWT.Dispose, SWT.FocusIn, SWT.FocusOut, SWT.KeyDown, SWT.Paint, SWT.Traverse };
+ for (int i = 0; i < events.length; i++) {
+ addListener(events[i], listener);
+ }
+
+ treeListener = new Listener() {
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.Collapse:
+ treeCollapse(event);
+ break;
+ case SWT.Expand:
+ treeExpand(event);
+ break;
+ case SWT.FocusIn:
+ treeFocusIn(event);
+ break;
+ case SWT.MouseDown:
+ treeMouseDown(event);
+ break;
+ }
+ }
+ };
+ tree.addListener(SWT.Collapse, treeListener);
+ tree.addListener(SWT.Expand, treeListener);
+ tree.addListener(SWT.FocusIn, treeListener);
+ tree.addListener(SWT.MouseDown, treeListener);
+
+ disposeItemListener = new Listener() {
+ public void handleEvent(Event event) {
+ TreeItem currentItem = row;
+ while (currentItem != null) {
+ currentItem.removeListener(SWT.Dispose, disposeItemListener);
+ currentItem = currentItem.getParentItem();
+ }
+ TreeItem disposedItem = (TreeItem)event.widget;
+ TreeItem parentItem = disposedItem.getParentItem();
+ if (parentItem != null) {
+ setRowColumn(parentItem, column, true);
+ } else {
+ if (tree.getItemCount() == 1) {
+ unhookRowColumnListeners();
+ } else {
+ TreeItem newFocus = null;
+ int rowIndex = tree.indexOf(disposedItem);
+ if (rowIndex != 0) {
+ TreeItem previousItem = tree.getItem(rowIndex - 1);
+ if (!previousItem.isDisposed()) {
+ newFocus = previousItem;
+ }
+ }
+ if (newFocus == null && rowIndex + 1 < tree.getItemCount()) {
+ TreeItem nextItem = tree.getItem(rowIndex + 1);
+ if (!nextItem.isDisposed()) {
+ newFocus = nextItem;
+ }
+ }
+ if (newFocus != null) {
+ setRowColumn(newFocus, column, true);
+ } else {
+ unhookRowColumnListeners();
+ }
+ }
+ }
+ _resize();
+ }
+ };
+ disposeColumnListener = new Listener() {
+ public void handleEvent(Event event) {
+ if (column != null) {
+ if (tree.getColumnCount() == 1) {
+ column = null;
+ } else {
+ int columnIndex = tree.indexOf(column);
+ int positionIndex = columnIndex;
+ int[] columnOrder = tree.getColumnOrder();
+ for (int i = 0; i < columnOrder.length; i++) {
+ if (columnOrder[i] == columnIndex) {
+ positionIndex = i;
+ break;
+ }
+ }
+ if (positionIndex == columnOrder.length - 1) {
+ setRowColumn(row, tree.getColumn(columnOrder[positionIndex - 1]), true);
+ } else {
+ setRowColumn(row, tree.getColumn(columnOrder[positionIndex + 1]), true);
+ }
+ }
+ }
+ _resize();
+ }
+ };
+ resizeListener = new Listener() {
+ public void handleEvent(Event event) {
+ _resize();
+ }
+ };
+ ScrollBar hBar = tree.getHorizontalBar();
+ if (hBar != null) {
+ hBar.addListener(SWT.Selection, resizeListener);
+ }
+ ScrollBar vBar = tree.getVerticalBar();
+ if (vBar != null) {
+ vBar.addListener(SWT.Selection, resizeListener);
+ }
+
+ getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() {
+ public void getRole(AccessibleControlEvent e) {
+ e.detail = ACC.ROLE_TABLECELL;
+ }
+ });
+ getAccessible().addAccessibleListener(new AccessibleAdapter() {
+ public void getName(AccessibleEvent e) {
+ if (row == null) return;
+ int columnIndex = column == null ? 0 : tree.indexOf(column);
+ e.result = row.getText(columnIndex);
+ }
+ });
+}
+
+/**
+ * Adds the listener to the collection of listeners who will be notified when the receiver's
+ * selection changes, by sending it one of the messages defined in the
+ * <code>SelectionListener</code> interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the item field of the event object is valid. If
+ * the receiver has <code>SWT.CHECK</code> style set and the check selection changes, the event
+ * object detail field contains the value <code>SWT.CHECK</code>.
+ * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see SelectionEvent
+ * @see #removeSelectionListener(SelectionListener)
+ */
+public void addSelectionListener(SelectionListener listener) {
+ checkWidget();
+ if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.Selection, typedListener);
+ addListener(SWT.DefaultSelection, typedListener);
+}
+
+int countSubTreePages(TreeItem root) {
+ int pages = 1;
+ if (root == null) return 0;
+ if (root.getItemCount() == 0) return 1;
+ if (!root.getExpanded()) return 1;
+ TreeItem[] items = root.getItems();
+ for (int i = 0; i < items.length; i++) {
+ pages += countSubTreePages(items[i]);
+ }
+ return pages;
+}
+
+int findIndex(TreeItem[] items, TreeItem treeItem) {
+ if (items == null || treeItem == null) return -1;
+ Rectangle rect = treeItem.getBounds();
+ int index = 0;
+ for (int i = 0; i < items.length; i++) {
+ TreeItem previousItem = null;
+ TreeItem currentItem = items[i];
+ if (i > 0) previousItem = items[i - 1];
+ Rectangle rect1 = currentItem.getBounds();
+ if (rect.y == rect1.y) return index;
+ if (rect.y < rect1.y) {
+ return index - 1 + findIndex(previousItem.getItems(), treeItem);
+ }
+ if (rect.y > rect1.y && i == items.length - 1) {
+ return index + findIndex(currentItem.getItems(), treeItem);
+ }
+ if (rect.y >= rect1.y + (1 + currentItem.getItemCount()) * tree.getItemHeight() && currentItem.getExpanded()) {
+ index += countSubTreePages(currentItem);
+ continue;
+ }
+ index++;
+ }
+ return -1;
+}
+
+TreeItem findItem(TreeItem[] items, Point pt) {
+ int start = 0, end = items.length - 1;
+ int index = end / 2;
+ while (end - start > 1) {
+ TreeItem currentItem = items[index];
+ Rectangle bounds = currentItem.getBounds();
+ if (pt.y < bounds.y) {
+ end = index;
+ index = (end - start) / 2;
+ } else {
+ start = index;
+ index = start + ((end - start) / 2);
+ }
+ }
+
+ Rectangle endBounds = items[end].getBounds();
+ if (endBounds.y < pt.y) {
+ if (endBounds.y + endBounds.height < pt.y) {
+ if (!items[end].getExpanded()) return null;
+ return findItem(items[end].getItems(), pt);
+ }
+ int[] columnOrder = tree.getColumnOrder();
+ Rectangle bounds = null;
+ if (columnOrder.length > 0) {
+ Rectangle rect1 = items[end].getBounds(columnOrder[0]);
+ Rectangle rect2 = items[end].getBounds(columnOrder[columnOrder.length - 1]);
+ bounds = rect1.union(rect2);
+ bounds.height += tree.getLinesVisible() ? tree.getGridLineWidth() : 0;
+ } else {
+ bounds = items[end].getBounds();
+ }
+ return bounds.contains(pt) ? items[end] : null;
+ }
+
+ Rectangle startBounds = items[start].getBounds();
+ if (startBounds.y + startBounds.height < pt.y) {
+ return findItem(items[start].getItems(), pt);
+ }
+ int[] columnOrder = tree.getColumnOrder();
+ Rectangle bounds = null;
+ if (columnOrder.length > 0) {
+ Rectangle rect1 = items[start].getBounds(columnOrder[0]);
+ Rectangle rect2 = items[start].getBounds(columnOrder[columnOrder.length - 1]);
+ bounds = rect1.union(rect2);
+ bounds.height += tree.getLinesVisible() ? tree.getGridLineWidth() : 0;
+ } else {
+ bounds = items[start].getBounds();
+ }
+ return bounds.contains(pt) ? items[start] : null;
+}
+
+/**
+ * Returns the background color that the receiver will use to draw.
+ *
+ * @return the receiver's background color
+ */
+public Color getBackground() {
+ checkWidget();
+ if (background == null) {
+ return getDisplay().getSystemColor(BACKGROUND);
+ }
+ return background;
+}
+
+/**
+ * Returns the index of the column over which the TreeCursor is positioned.
+ *
+ * @return the column index for the current position
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getColumn() {
+ checkWidget();
+ return column == null ? 0 : tree.indexOf(column);
+}
+
+/**
+ * Returns the foreground color that the receiver will use to draw.
+ *
+ * @return the receiver's foreground color
+ */
+public Color getForeground() {
+ checkWidget();
+ if (foreground == null) {
+ return getDisplay().getSystemColor(FOREGROUND);
+ }
+ return foreground;
+}
+
+TreeItem getLastVisibleItem(TreeItem[] items) {
+ if (items == null) return null;
+ TreeItem last = items[items.length - 1];
+ if (last.getExpanded() && last.getItemCount() > 0) {
+ return getLastVisibleItem(last.getItems());
+ }
+ return last;
+}
+
+TreeItem getNextItem(TreeItem item) {
+ if (item == null) return null;
+ if (item.getExpanded() && item.getItemCount() > 0) {
+ return item.getItem(0);
+ }
+
+ TreeItem parentItem = item.getParentItem();
+ while (parentItem != null) {
+ int index = parentItem.indexOf(item);
+ if (index == -1) return null;
+ if (index < parentItem.getItemCount() - 1) {
+ return parentItem.getItem(index + 1);
+ }
+ item = parentItem;
+ parentItem = item.getParentItem();
+ }
+ int index = tree.indexOf(item);
+ if (index == -1) return null;
+ if (index == tree.getItemCount() - 1) return null;
+ return tree.getItem(index + 1);
+}
+
+TreeItem getPreviousItem(TreeItem item) {
+ if (item == null) return null;
+ TreeItem parentItem = item.getParentItem();
+ if (parentItem == null) {
+ int index = tree.indexOf(item);
+ if (index == -1 || index == 0) return null;
+ item = tree.getItem(index - 1);
+ if (item.getExpanded() && item.getItemCount() > 0) {
+ return getLastVisibleItem(item.getItems());
+ }
+ return item;
+ }
+ int index = parentItem.indexOf(item);
+ if (index == -1) return null;
+ if (index == 0) return parentItem;
+ item = parentItem.getItem(index - 1);
+ if (item.getExpanded() && item.getItemCount() > 0) {
+ return getLastVisibleItem(item.getItems());
+ }
+ return item;
+}
+
+/**
+ * Returns the row over which the TreeCursor is positioned.
+ *
+ * @return the item for the current position, or <code>null</code> if none
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem getRow() {
+ checkWidget();
+ return row;
+}
+
+void keyDown(Event event) {
+ if (row == null) return;
+ switch (event.character) {
+ case SWT.CR:
+ notifyListeners(SWT.DefaultSelection, new Event());
+ return;
+ }
+ switch (event.keyCode) {
+ case SWT.ARROW_UP:
+ TreeItem previousItem = getPreviousItem(row);
+ if (previousItem != null) {
+ setRowColumn(previousItem, column, true);
+ }
+ break;
+ case SWT.ARROW_DOWN:
+ TreeItem nextItem = getNextItem(row);
+ if (nextItem != null) {
+ setRowColumn(nextItem, column, true);
+ }
+ break;
+ case SWT.ARROW_LEFT:
+ case SWT.ARROW_RIGHT: {
+ if ((event.stateMask & SWT.MOD1) != 0) {
+ row.setExpanded (event.keyCode == SWT.ARROW_RIGHT);
+ break;
+ }
+ int columnCount = tree.getColumnCount();
+ if (columnCount == 0) break;
+ int columnIndex = column == null ? 0 : tree.indexOf(column);
+ int[] columnOrder = tree.getColumnOrder();
+ int index = 0;
+ while (index < columnOrder.length) {
+ if (columnOrder[index] == columnIndex) break;
+ index++;
+ }
+ if (index == columnOrder.length) index = 0;
+ int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
+ TreeItem parentRow = row.getParentItem();
+ int rowIndex = tree.indexOf(row);
+ if (event.keyCode == leadKey) {
+ if (parentRow != null) {
+ setRowColumn(row, tree.getColumn(columnOrder[Math.max(0, index - 1)]), true);
+ } else {
+ setRowColumn(rowIndex, columnOrder[Math.max(0, index - 1)], true);
+ }
+ } else {
+ if (parentRow != null) {
+ setRowColumn(row, tree.getColumn(columnOrder[Math.min(columnCount - 1, index + 1)]), true);
+ } else {
+ setRowColumn(rowIndex, columnOrder[Math.min(columnCount - 1, index + 1)], true);
+ }
+ }
+ break;
+ }
+ case SWT.HOME:
+ int columnIndex = column == null ? 0 : tree.indexOf(column);
+ setRowColumn(0, columnIndex, true);
+ break;
+ case SWT.END: {
+ TreeItem[] items = tree.getItems();
+ setRowColumn(getLastVisibleItem(items), column, true);
+ break;
+ }
+ case SWT.PAGE_UP: {
+ Rectangle rect = tree.getClientArea();
+ Rectangle itemRect = tree.getTopItem().getBounds();
+ TreeItem item = row;
+ int index = findIndex(tree.getItems(), item);
+ int itemHeight = tree.getItemHeight();
+ rect.height -= itemRect.y;
+ int page = Math.max(1, rect.height / itemHeight);
+ if (index - page <= 0) {
+ TreeItem first = tree.getItem(0);
+ setRowColumn(first, column, true);
+ break;
+ }
+ for (int i = 0; i < page; i++) {
+ item = getPreviousItem(item);
+ }
+ setRowColumn(item, column, true);
+ break;
+ }
+ case SWT.PAGE_DOWN: {
+ Rectangle rect = tree.getClientArea();
+ Rectangle itemRect = tree.getTopItem().getBounds();
+ TreeItem item = row;
+ int index = findIndex(tree.getItems(), item);
+ int height = tree.getItemHeight();
+ rect.height -= itemRect.y;
+ TreeItem last = getLastVisibleItem(tree.getItems());
+ int page = Math.max(1, rect.height / height);
+ int end = findIndex(tree.getItems(), last);
+ if (end <= index + page) {
+ setRowColumn(last, column, true);
+ break;
+ }
+ for (int i = 0; i < page; i++) {
+ item = getNextItem(item);
+ }
+ setRowColumn(item, column, true);
+ break;
+ }
+ }
+}
+
+void onDispose(Event event) {
+ removeListener(SWT.Dispose, listener);
+ notifyListeners(SWT.Dispose, event);
+ event.type = SWT.None;
+
+ tree.removeListener(SWT.Collapse, treeListener);
+ tree.removeListener(SWT.Expand, treeListener);
+ tree.removeListener(SWT.FocusIn, treeListener);
+ tree.removeListener(SWT.MouseDown, treeListener);
+ unhookRowColumnListeners();
+ ScrollBar hBar = tree.getHorizontalBar();
+ if (hBar != null) {
+ hBar.removeListener(SWT.Selection, resizeListener);
+ }
+ ScrollBar vBar = tree.getVerticalBar();
+ if (vBar != null) {
+ vBar.removeListener(SWT.Selection, resizeListener);
+ }
+}
+
+void paint(Event event) {
+ if (row == null) return;
+ int columnIndex = column == null ? 0 : tree.indexOf(column);
+ int orderedIndex = columnIndex;
+ int[] columnOrder = tree.getColumnOrder();
+ for (int i = 0; i < columnOrder.length; i++) {
+ if (columnOrder[i] == columnIndex) {
+ orderedIndex = i;
+ break;
+ }
+ }
+ GC gc = event.gc;
+ gc.setBackground(getBackground());
+ gc.setForeground(getForeground());
+ gc.fillRectangle(event.x, event.y, event.width, event.height);
+ Image image = row.getImage(columnIndex);
+ int x = 0;
+ // Temporary code - need a better way to determine trim
+ String platform = SWT.getPlatform();
+ if (image != null) {
+ if ("win32".equals(platform)) { //$NON-NLS-1$
+ if (orderedIndex > 0) {
+ x += 2;
+ }
+ } else {
+ x += 2;
+ }
+ }
+ Point size = getSize();
+ if (image != null) {
+ Rectangle imageSize = image.getBounds();
+ int imageY = (size.y - imageSize.height) / 2;
+ gc.drawImage(image, x, imageY);
+ x += imageSize.width;
+ }
+ String text = row.getText(columnIndex);
+ if (text.length() > 0) {
+ Rectangle bounds = row.getBounds(columnIndex);
+ Point extent = gc.stringExtent(text);
+ // Temporary code - need a better way to determine trim
+ if ("win32".equals(platform)) { //$NON-NLS-1$
+ if (tree.getColumnCount() == 0 || orderedIndex == 0) {
+ x += image == null ? 2 : 5;
+ } else {
+ int alignmnent = column.getAlignment();
+ switch (alignmnent) {
+ case SWT.LEFT:
+ x += image == null ? 5 : 3;
+ break;
+ case SWT.RIGHT:
+ x = bounds.width - extent.x - 2;
+ break;
+ case SWT.CENTER:
+ x += Math.ceil((bounds.width - x - extent.x) / 2.0);
+ break;
+ }
+ }
+ } else {
+ if (tree.getColumnCount() == 0) {
+ x += image == null ? 4 : 3;
+ } else {
+ int alignmnent = column.getAlignment();
+ switch (alignmnent) {
+ case SWT.LEFT:
+ x += image == null ? 5 : 3;
+ break;
+ case SWT.RIGHT:
+ x = bounds.width - extent.x - 2;
+ break;
+ case SWT.CENTER:
+ x += (bounds.width - x - extent.x) / 2 + 2;
+ break;
+ }
+ }
+ }
+ int textY = (size.y - extent.y) / 2;
+ gc.drawString(text, x, textY);
+ }
+ if (isFocusControl()) {
+ Display display = getDisplay();
+ gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+ gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
+ gc.drawFocus(0, 0, size.x, size.y);
+ }
+}
+
+/**
+ * Removes the listener from the collection of listeners who will be notified when the
+ * receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener(SelectionListener)
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget();
+ if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ removeListener(SWT.Selection, listener);
+ removeListener(SWT.DefaultSelection, listener);
+}
+
+void _resize() {
+ if (row == null) {
+ setBounds(-200, -200, 0, 0);
+ } else {
+ int columnIndex = column == null ? 0 : tree.indexOf(column);
+ setBounds(row.getBounds(columnIndex));
+ }
+}
+
+/**
+ * Sets the receiver's background color to the color specified
+ * by the argument, or to the default system color for the control
+ * if the argument is null.
+ * <p>
+ * Note: This operation is a hint and may be overridden by the platform.
+ * For example, on Windows the background of a Button cannot be changed.
+ * </p>
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBackground (Color color) {
+ background = color;
+ super.setBackground(getBackground());
+ redraw();
+}
+/**
+ * Sets the receiver's foreground color to the color specified
+ * by the argument, or to the default system color for the control
+ * if the argument is null.
+ * <p>
+ * Note: This operation is a hint and may be overridden by the platform.
+ * </p>
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setForeground (Color color) {
+ foreground = color;
+ super.setForeground(getForeground());
+ redraw();
+}
+
+void setRowColumn(int row, int column, boolean notify) {
+ TreeItem item = row == -1 ? null : tree.getItem(row);
+ TreeColumn col = column == -1 || tree.getColumnCount() == 0 ? null : tree.getColumn(column);
+ setRowColumn(item, col, notify);
+}
+
+void setRowColumn(TreeItem row, TreeColumn column, boolean notify) {
+ if (this.row != null && this.row != row) {
+ TreeItem currentItem = this.row;
+ while (currentItem != null) {
+ currentItem.removeListener(SWT.Dispose, disposeItemListener);
+ currentItem = currentItem.getParentItem();
+ }
+ this.row = null;
+ }
+ if (this.column != null && this.column != column) {
+ this.column.removeListener(SWT.Dispose, disposeColumnListener);
+ this.column.removeListener(SWT.Move, resizeListener);
+ this.column.removeListener(SWT.Resize, resizeListener);
+ this.column = null;
+ }
+ if (row != null) {
+ if (this.row != row) {
+ this.row = row;
+ TreeItem currentItem = row;
+ while (currentItem != null) {
+ currentItem.addListener(SWT.Dispose, disposeItemListener);
+ currentItem = currentItem.getParentItem();
+ }
+ tree.showItem(row);
+ }
+ if (this.column != column && column != null) {
+ this.column = column;
+ column.addListener(SWT.Dispose, disposeColumnListener);
+ column.addListener(SWT.Move, resizeListener);
+ column.addListener(SWT.Resize, resizeListener);
+ tree.showColumn(column);
+ }
+ int columnIndex = column == null ? 0 : tree.indexOf(column);
+ setBounds(row.getBounds(columnIndex));
+ redraw();
+ if (notify) notifyListeners(SWT.Selection, new Event());
+ }
+}
+
+/**
+ * Positions the TreeCursor over the root-level cell at the given row and column in the parent tree.
+ *
+ * @param row the index of the root-level row for the cell to select
+ * @param column the index of column for the cell to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection(int row, int column) {
+ checkWidget();
+ int columnCount = tree.getColumnCount();
+ int maxColumnIndex = columnCount == 0 ? 0 : columnCount - 1;
+ if (row < 0 || row >= tree.getItemCount() || column < 0 || column > maxColumnIndex) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ setRowColumn(row, column, false);
+}
+
+/**
+ * Positions the TreeCursor over the cell at the given row and column in the parent tree.
+ *
+ * @param row the TreeItem of the row for the cell to select
+ * @param column the index of column for the cell to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection(TreeItem row, int column) {
+ checkWidget();
+ int columnCount = tree.getColumnCount();
+ int maxColumnIndex = columnCount == 0 ? 0 : columnCount - 1;
+ if (row == null || row.isDisposed() || column < 0 || column > maxColumnIndex) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ TreeColumn col = tree.getColumnCount() == 0 ? null : tree.getColumn(column);
+ setRowColumn(row, col, false);
+}
+
+public void setVisible(boolean visible) {
+ checkWidget();
+ if (visible) {
+ _resize();
+ }
+ super.setVisible(visible);
+}
+
+void treeCollapse(Event event) {
+ if (row == null) return;
+ TreeItem root = (TreeItem)event.item;
+ TreeItem parentItem = row.getParentItem();
+ while (parentItem != null) {
+ if (parentItem == root) {
+ setRowColumn(root, column, true);
+ return;
+ }
+ parentItem = parentItem.getParentItem();
+ }
+
+ getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (isDisposed()) return;
+ setRowColumn(row, column, true);
+ }
+ });
+}
+
+void treeExpand(Event event) {
+ getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (isDisposed()) return;
+ setRowColumn(row, column, true);
+ }
+ });
+}
+
+void treeFocusIn(Event event) {
+ if (isVisible()) {
+ if (row == null && column == null) return;
+ setFocus();
+ }
+}
+
+void treeMouseDown(Event event) {
+ if (tree.getItemCount() == 0) return;
+ Point pt = new Point(event.x, event.y);
+ TreeItem item = tree.getItem(pt);
+ if (item == null && (tree.getStyle() & SWT.FULL_SELECTION) == 0) {
+ TreeItem currentItem = tree.getTopItem();
+ TreeItem parentItem = currentItem.getParentItem();
+ while (parentItem != null) {
+ currentItem = parentItem;
+ parentItem = currentItem.getParentItem();
+ }
+ int start = tree.indexOf(currentItem);
+ int viewportItemCount = tree.getClientArea().height / tree.getItemHeight();
+ int end = Math.min(start + viewportItemCount, tree.getItemCount() - 1);
+ TreeItem[] allItems = tree.getItems();
+ TreeItem[] items = new TreeItem[end - start + 1];
+ System.arraycopy(allItems, start, items, 0, end - start + 1);
+ item = findItem(items, pt);
+ }
+ if (item == null) return;
+
+ TreeColumn newColumn = null;
+ int lineWidth = tree.getLinesVisible() ? tree.getGridLineWidth() : 0;
+ int columnCount = tree.getColumnCount();
+ if (columnCount > 0) {
+ for (int i = 0; i < columnCount; i++) {
+ Rectangle rect = item.getBounds(i);
+ rect.width += lineWidth;
+ rect.height += lineWidth;
+ if (rect.contains(pt)) {
+ newColumn = tree.getColumn(i);
+ break;
+ }
+ }
+ if (newColumn == null) {
+ newColumn = tree.getColumn(0);
+ }
+ }
+ setRowColumn(item, newColumn, true);
+ setFocus();
+}
+
+void unhookRowColumnListeners() {
+ if (column != null && !column.isDisposed()) {
+ column.removeListener(SWT.Dispose, disposeColumnListener);
+ column.removeListener(SWT.Move, resizeListener);
+ column.removeListener(SWT.Resize, resizeListener);
+ }
+ column = null;
+ if (row != null && !row.isDisposed()) {
+ TreeItem currentItem = row;
+ while (currentItem != null) {
+ currentItem.removeListener(SWT.Dispose, disposeItemListener);
+ currentItem = currentItem.getParentItem();
+ }
+ }
+ row = null;
+}
+
+}