|
Added
Link Here
|
| 1 |
package org.eclipse.ui.internal.incubator; |
| 2 |
|
| 3 |
import org.eclipse.jface.dialogs.Dialog; |
| 4 |
import org.eclipse.jface.dialogs.PopupDialog; |
| 5 |
import org.eclipse.jface.layout.GridDataFactory; |
| 6 |
import org.eclipse.jface.resource.DeviceResourceException; |
| 7 |
import org.eclipse.jface.resource.ImageDescriptor; |
| 8 |
import org.eclipse.jface.resource.JFaceResources; |
| 9 |
import org.eclipse.jface.resource.LocalResourceManager; |
| 10 |
import org.eclipse.swt.SWT; |
| 11 |
import org.eclipse.swt.events.KeyEvent; |
| 12 |
import org.eclipse.swt.events.KeyListener; |
| 13 |
import org.eclipse.swt.events.ModifyEvent; |
| 14 |
import org.eclipse.swt.events.ModifyListener; |
| 15 |
import org.eclipse.swt.graphics.Color; |
| 16 |
import org.eclipse.swt.graphics.FontMetrics; |
| 17 |
import org.eclipse.swt.graphics.GC; |
| 18 |
import org.eclipse.swt.graphics.Image; |
| 19 |
import org.eclipse.swt.graphics.Rectangle; |
| 20 |
import org.eclipse.swt.widgets.Composite; |
| 21 |
import org.eclipse.swt.widgets.Control; |
| 22 |
import org.eclipse.swt.widgets.Event; |
| 23 |
import org.eclipse.swt.widgets.Listener; |
| 24 |
import org.eclipse.swt.widgets.Shell; |
| 25 |
import org.eclipse.swt.widgets.Table; |
| 26 |
import org.eclipse.swt.widgets.TableColumn; |
| 27 |
import org.eclipse.swt.widgets.TableItem; |
| 28 |
import org.eclipse.swt.widgets.Text; |
| 29 |
import org.eclipse.ui.internal.IWorkbenchGraphicConstants; |
| 30 |
import org.eclipse.ui.internal.WorkbenchImages; |
| 31 |
import org.eclipse.ui.internal.WorkbenchPlugin; |
| 32 |
import org.eclipse.ui.internal.misc.StringMatcher; |
| 33 |
|
| 34 |
/** |
| 35 |
* @since 3.3 |
| 36 |
* |
| 37 |
*/ |
| 38 |
public class QuickAccessDialog extends PopupDialog { |
| 39 |
private static final int MAX_COUNT_PER_PROVIDER = 5; |
| 40 |
private static final int MAX_COUNT_TOTAL = 20; |
| 41 |
private Text filterText; |
| 42 |
private AbstractProvider[] providers; |
| 43 |
private Table table; |
| 44 |
private LocalResourceManager resourceManager = new LocalResourceManager( |
| 45 |
JFaceResources.getResources()); |
| 46 |
|
| 47 |
/** |
| 48 |
* @param parent |
| 49 |
* @param providers |
| 50 |
*/ |
| 51 |
QuickAccessDialog(Shell parent, AbstractProvider[] providers) { |
| 52 |
super(parent, SWT.RESIZE, true, true, true, true, "Foo", "foo"); //$NON-NLS-1$ //$NON-NLS-2$ |
| 53 |
this.providers = providers; |
| 54 |
} |
| 55 |
|
| 56 |
protected Control createTitleControl(Composite parent) { |
| 57 |
filterText = new Text(parent, SWT.NONE); |
| 58 |
|
| 59 |
GC gc = new GC(parent); |
| 60 |
gc.setFont(parent.getFont()); |
| 61 |
FontMetrics fontMetrics = gc.getFontMetrics(); |
| 62 |
gc.dispose(); |
| 63 |
|
| 64 |
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, |
| 65 |
false).hint(SWT.DEFAULT, |
| 66 |
Dialog.convertHeightInCharsToPixels(fontMetrics, 1)).applyTo( |
| 67 |
filterText); |
| 68 |
|
| 69 |
filterText.addKeyListener(new KeyListener() { |
| 70 |
public void keyPressed(KeyEvent e) { |
| 71 |
if (e.keyCode == 0x0D) { |
| 72 |
// return |
| 73 |
// Object selectedElement = getSelectedElement(); |
| 74 |
close(); |
| 75 |
// handleElementSelected(selectedElement); |
| 76 |
} |
| 77 |
if (e.keyCode == SWT.ARROW_DOWN) |
| 78 |
table.setFocus(); |
| 79 |
if (e.keyCode == SWT.ARROW_UP) |
| 80 |
table.setFocus(); |
| 81 |
if (e.character == 0x1B) // ESC |
| 82 |
close(); |
| 83 |
} |
| 84 |
|
| 85 |
public void keyReleased(KeyEvent e) { |
| 86 |
// do nothing |
| 87 |
} |
| 88 |
}); |
| 89 |
filterText.addModifyListener(new ModifyListener() { |
| 90 |
public void modifyText(ModifyEvent e) { |
| 91 |
String text = ((Text) e.widget).getText(); |
| 92 |
int length = text.length(); |
| 93 |
if (length > 0) { |
| 94 |
if (text.charAt(length - 1) != '*') { |
| 95 |
text = text + '*'; |
| 96 |
} |
| 97 |
if (text.charAt(0) != '*') { |
| 98 |
text = '*' + text; |
| 99 |
} |
| 100 |
} |
| 101 |
refreshTable(text); |
| 102 |
} |
| 103 |
}); |
| 104 |
|
| 105 |
return filterText; |
| 106 |
} |
| 107 |
|
| 108 |
/* |
| 109 |
* (non-Javadoc) |
| 110 |
* |
| 111 |
* @see org.eclipse.jface.dialogs.PopupDialog#createDialogArea(org.eclipse.swt.widgets.Composite) |
| 112 |
*/ |
| 113 |
protected Control createDialogArea(Composite parent) { |
| 114 |
Composite composite = (Composite) super.createDialogArea(parent); |
| 115 |
table = new Table(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL |
| 116 |
| SWT.BORDER | SWT.FULL_SELECTION); |
| 117 |
new TableColumn(table, SWT.NONE).setWidth(100); |
| 118 |
new TableColumn(table, SWT.NONE).setWidth(300); |
| 119 |
GridDataFactory.fillDefaults().grab(true, true).applyTo(table); |
| 120 |
// table.addListener(SWT.MeasureItem, new Listener() { |
| 121 |
// public void handleEvent(Event event) { |
| 122 |
// TableEntry entry = (TableEntry) event.item.getData(); |
| 123 |
// } |
| 124 |
// }); |
| 125 |
//TextLayout layout = new TextLayout(table.getDisplay()); |
| 126 |
Listener listener = new Listener() { |
| 127 |
public void handleEvent(Event event) { |
| 128 |
switch (event.type) { |
| 129 |
case SWT.MeasureItem: |
| 130 |
break; |
| 131 |
case SWT.PaintItem: |
| 132 |
break; |
| 133 |
case SWT.EraseItem: |
| 134 |
Rectangle bounds = event.getBounds(); |
| 135 |
if ((event.detail & SWT.SELECTED) != 0) { |
| 136 |
Color oldForeground = event.gc.getForeground(); |
| 137 |
Color oldBackground = event.gc.getBackground(); |
| 138 |
|
| 139 |
event.gc.setBackground(event.item.getDisplay() |
| 140 |
.getSystemColor(SWT.COLOR_LIST_SELECTION)); |
| 141 |
event.gc.setForeground(event.item.getDisplay() |
| 142 |
.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT)); |
| 143 |
event.gc.fillRectangle(bounds); |
| 144 |
/* restore the old GC colors */ |
| 145 |
event.gc.setForeground(oldForeground); |
| 146 |
event.gc.setBackground(oldBackground); |
| 147 |
/* ensure that default selection is not drawn */ |
| 148 |
event.detail &= ~SWT.SELECTED; |
| 149 |
} |
| 150 |
break; |
| 151 |
} |
| 152 |
} |
| 153 |
}; |
| 154 |
table.addListener(SWT.MeasureItem, listener); |
| 155 |
table.addListener(SWT.EraseItem, listener); |
| 156 |
table.addListener(SWT.PaintItem, listener); |
| 157 |
refreshTable(); |
| 158 |
return composite; |
| 159 |
} |
| 160 |
|
| 161 |
private static class TableEntry { |
| 162 |
boolean firstInCategory; |
| 163 |
AbstractElement element; |
| 164 |
|
| 165 |
TableEntry(boolean firstInCategory, AbstractElement element) { |
| 166 |
this.firstInCategory = firstInCategory; |
| 167 |
this.element = element; |
| 168 |
} |
| 169 |
} |
| 170 |
|
| 171 |
/** |
| 172 |
* |
| 173 |
*/ |
| 174 |
private void refreshTable() { |
| 175 |
String filter = filterText.getText(); |
| 176 |
refreshTable(filter); |
| 177 |
} |
| 178 |
|
| 179 |
/** |
| 180 |
* |
| 181 |
*/ |
| 182 |
private void refreshTable(String filter) { |
| 183 |
table.setRedraw(false); |
| 184 |
try { |
| 185 |
TableItem[] items = table.getItems(); |
| 186 |
StringMatcher stringMatcher = new StringMatcher(filter, true, false); |
| 187 |
int countTotal = 0; |
| 188 |
for (int i = 0; i < providers.length |
| 189 |
&& countTotal < MAX_COUNT_TOTAL; i++) { |
| 190 |
int countPerProvider = 0; |
| 191 |
AbstractProvider provider = providers[i]; |
| 192 |
AbstractElement[] elements = provider.getElements(); |
| 193 |
element_loop: for (int j = 0; j < elements.length |
| 194 |
&& countPerProvider < MAX_COUNT_PER_PROVIDER |
| 195 |
&& countTotal < MAX_COUNT_TOTAL; j++) { |
| 196 |
AbstractElement element = elements[j]; |
| 197 |
String[] matchLabels = element.getMatchLabels(); |
| 198 |
for (int k = 0; k < matchLabels.length; k++) { |
| 199 |
if (stringMatcher.match(matchLabels[k])) { |
| 200 |
boolean firstInCategory = countPerProvider == 0; |
| 201 |
TableEntry entry = new TableEntry(firstInCategory, |
| 202 |
element); |
| 203 |
TableItem item; |
| 204 |
if (countTotal < items.length) { |
| 205 |
item = items[countTotal]; |
| 206 |
} else { |
| 207 |
item = new TableItem(table, SWT.NONE); |
| 208 |
} |
| 209 |
item.setData(entry); |
| 210 |
if (firstInCategory) { |
| 211 |
item |
| 212 |
.setText(0, element.getProvider() |
| 213 |
.getName()); |
| 214 |
} |
| 215 |
item.setText(1, element.getLabel()); |
| 216 |
item.setImage(1, getImage(element)); |
| 217 |
countPerProvider++; |
| 218 |
countTotal++; |
| 219 |
continue element_loop; |
| 220 |
} |
| 221 |
} |
| 222 |
} |
| 223 |
} |
| 224 |
for (int i = countTotal; i < items.length; i++) { |
| 225 |
items[i].dispose(); |
| 226 |
} |
| 227 |
if (countTotal > 0) { |
| 228 |
table.setSelection(0); |
| 229 |
} else { |
| 230 |
table.deselectAll(); |
| 231 |
} |
| 232 |
} finally { |
| 233 |
table.setRedraw(true); |
| 234 |
} |
| 235 |
} |
| 236 |
|
| 237 |
private Image getImage(AbstractElement element) { |
| 238 |
Image image = findOrCreateImage(((AbstractElement) element) |
| 239 |
.getImageDescriptor()); |
| 240 |
if (image == null) { |
| 241 |
image = WorkbenchImages |
| 242 |
.getImage(IWorkbenchGraphicConstants.IMG_OBJ_ELEMENT); |
| 243 |
} |
| 244 |
return image; |
| 245 |
} |
| 246 |
|
| 247 |
private Image findOrCreateImage(ImageDescriptor imageDescriptor) { |
| 248 |
if (imageDescriptor == null) { |
| 249 |
return null; |
| 250 |
} |
| 251 |
Image image = (Image) resourceManager.find(imageDescriptor); |
| 252 |
if (image == null) { |
| 253 |
try { |
| 254 |
image = resourceManager.createImage(imageDescriptor); |
| 255 |
} catch (DeviceResourceException e) { |
| 256 |
WorkbenchPlugin.log(e); |
| 257 |
} |
| 258 |
} |
| 259 |
return image; |
| 260 |
} |
| 261 |
|
| 262 |
protected Control getFocusControl() { |
| 263 |
return filterText; |
| 264 |
} |
| 265 |
|
| 266 |
public boolean close() { |
| 267 |
if (resourceManager != null) { |
| 268 |
resourceManager.dispose(); |
| 269 |
resourceManager = null; |
| 270 |
} |
| 271 |
return super.close(); |
| 272 |
} |
| 273 |
} |