Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 8ae601273d00bb792d95751a9f08db5bca7eb05c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*******************************************************************************
 * Copyright (c) 2008 Software Competence Center Hagenberg (SCCH) GmbH
 * Copyright (c) 2008 Mario Winterer
 * 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
 *
 * Contibutors
 *     Hendrik Still <hendrik.still@gammas.de> - bug 417676
 *******************************************************************************/
package org.eclipse.jface.snippets.viewers;

import org.eclipse.jface.bindings.keys.IKeyLookup;
import org.eclipse.jface.bindings.keys.KeyLookupFactory;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposalListener2;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.FocusCellHighlighter;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;

/**
 * Shows how to attach content assist to a text cell editor.
 *
 * @author Mario Winterer
 */
public class Snippet060TextCellEditorWithContentProposal {
	private static class Color {
		public String name;

		public Color(String name) {
			this.name = name;
		}

		public String toString() {
			return name;
		}
	}

	public static class TextCellEditorWithContentProposal extends TextCellEditor {

		private ContentProposalAdapter contentProposalAdapter;
		private boolean popupOpen = false; // true, iff popup is currently open

		public TextCellEditorWithContentProposal(Composite parent, IContentProposalProvider contentProposalProvider,
				KeyStroke keyStroke, char[] autoActivationCharacters) {
			super(parent);

			enableContentProposal(contentProposalProvider, keyStroke, autoActivationCharacters);
		}

		private void enableContentProposal(IContentProposalProvider contentProposalProvider, KeyStroke keyStroke,
				char[] autoActivationCharacters) {
			contentProposalAdapter = new ContentProposalAdapter(text, new TextContentAdapter(),
					contentProposalProvider, keyStroke, autoActivationCharacters);

			// Listen for popup open/close events to be able to handle focus events correctly
			contentProposalAdapter.addContentProposalListener(new IContentProposalListener2() {

				public void proposalPopupClosed(ContentProposalAdapter adapter) {
					popupOpen = false;
				}

				public void proposalPopupOpened(ContentProposalAdapter adapter) {
					popupOpen = true;
				}
			});
		}

		/**
		 * Return the {@link ContentProposalAdapter} of this cell editor.
		 *
		 * @return the {@link ContentProposalAdapter}
		 */
		public ContentProposalAdapter getContentProposalAdapter() {
			return contentProposalAdapter;
		}

		protected void focusLost() {
			if (!popupOpen) {
				// Focus lost deactivates the cell editor.
				// This must not happen if focus lost was caused by activating
				// the completion proposal popup.
				super.focusLost();
			}
		}

		protected boolean dependsOnExternalFocusListener() {
			// Always return false;
			// Otherwise, the ColumnViewerEditor will install an additional focus listener
			// that cancels cell editing on focus lost, even if focus gets lost due to
			// activation of the completion proposal popup. See also bug 58777.
			return false;
		}
	}

	private static class ColorNameEditingSupport extends EditingSupport {
		private TextCellEditorWithContentProposal cellEditor;

		public ColorNameEditingSupport(TableViewer viewer) {
			super(viewer);

			IContentProposalProvider contentProposalProvider = new SimpleContentProposalProvider(new String[] { "red",
					"green", "blue" });
			cellEditor = new TextCellEditorWithContentProposal(viewer.getTable(), contentProposalProvider, null, null);
		}

		protected boolean canEdit(Object element) {
			return (element instanceof Color);
		}

		protected CellEditor getCellEditor(Object element) {
			return cellEditor;
		}

		protected Object getValue(Object element) {
			return ((Color) element).name;
		}

		protected void setValue(Object element, Object value) {
			((Color) element).name = value.toString();
			getViewer().update(element, null);
		}

	}

	public Snippet060TextCellEditorWithContentProposal(Shell shell) {
		final TableViewer<Color,Object> viewer = new TableViewer<Color,Object>(shell, SWT.BORDER | SWT.FULL_SELECTION);
		final Table table = viewer.getTable();
		table.setLinesVisible(true);
		table.setHeaderVisible(true);

		final TableViewerColumn<Color,Object> colorColumn = new TableViewerColumn<Color,Object>(viewer, SWT.LEFT);
		colorColumn.getColumn().setText("Color name");
		colorColumn.getColumn().setWidth(200);
		colorColumn.setLabelProvider(new ColumnLabelProvider<Color,Object>());
		colorColumn.setEditingSupport(new ColorNameEditingSupport(viewer));

		viewer.setContentProvider(new ArrayContentProvider<Color>(Color.class));

		ColumnViewerEditorActivationStrategy activationSupport = new ColumnViewerEditorActivationStrategy(viewer) {
			protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
				return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
						|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
						|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC
						|| (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == KeyLookupFactory
								.getDefault().formalKeyLookup(IKeyLookup.ENTER_NAME));
			}
		};
		activationSupport.setEnableEditorActivationWithKeyboard(true);

		/*
		 * Without focus highlighter, keyboard events will not be delivered to
		 * ColumnViewerEditorActivationStragety#isEditorActivationEvent(...) (see above)
		 */
		FocusCellHighlighter focusCellHighlighter = new FocusCellOwnerDrawHighlighter(viewer);
		TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(viewer, focusCellHighlighter);

		TableViewerEditor.create(viewer, focusCellManager, activationSupport, ColumnViewerEditor.TABBING_VERTICAL
				| ColumnViewerEditor.KEYBOARD_ACTIVATION);

		viewer.setInput(createModel());
	}

	private Color[] createModel() {
		return new Color[] { new Color("red"), new Color("green") };
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Display display = new Display();

		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		new Snippet060TextCellEditorWithContentProposal(shell);
		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}

		display.dispose();
	}
}

Back to the top