Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2010 IBM Corporation and others. |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/epl-v10.html |
7 |
* |
8 |
* Contributors: |
9 |
* IBM Corporation - initial API and implementation |
10 |
******************************************************************************/ |
11 |
|
12 |
package org.eclipse.ui.internal.views.markers; |
13 |
|
14 |
import java.util.ArrayList; |
15 |
import java.util.Arrays; |
16 |
import java.util.Iterator; |
17 |
import java.util.List; |
18 |
import java.util.ListIterator; |
19 |
import java.util.Random; |
20 |
|
21 |
import org.eclipse.core.runtime.IStatus; |
22 |
import org.eclipse.jface.dialogs.Dialog; |
23 |
import org.eclipse.jface.resource.JFaceResources; |
24 |
import org.eclipse.jface.viewers.ISelection; |
25 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
26 |
import org.eclipse.jface.viewers.IStructuredContentProvider; |
27 |
import org.eclipse.jface.viewers.IStructuredSelection; |
28 |
import org.eclipse.jface.viewers.ITableLabelProvider; |
29 |
import org.eclipse.jface.viewers.LabelProvider; |
30 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
31 |
import org.eclipse.jface.viewers.TableViewer; |
32 |
import org.eclipse.jface.viewers.Viewer; |
33 |
import org.eclipse.swt.SWT; |
34 |
import org.eclipse.swt.custom.CLabel; |
35 |
import org.eclipse.swt.graphics.Image; |
36 |
import org.eclipse.swt.layout.FillLayout; |
37 |
import org.eclipse.swt.layout.GridData; |
38 |
import org.eclipse.swt.layout.GridLayout; |
39 |
import org.eclipse.swt.widgets.Button; |
40 |
import org.eclipse.swt.widgets.Composite; |
41 |
import org.eclipse.swt.widgets.Control; |
42 |
import org.eclipse.swt.widgets.Display; |
43 |
import org.eclipse.swt.widgets.Event; |
44 |
import org.eclipse.swt.widgets.Group; |
45 |
import org.eclipse.swt.widgets.Label; |
46 |
import org.eclipse.swt.widgets.Listener; |
47 |
import org.eclipse.swt.widgets.Shell; |
48 |
import org.eclipse.swt.widgets.Table; |
49 |
import org.eclipse.swt.widgets.TableColumn; |
50 |
import org.eclipse.swt.widgets.Text; |
51 |
import org.eclipse.ui.preferences.ViewSettingsDialog; |
52 |
import org.eclipse.ui.views.markers.internal.MarkerMessages; |
53 |
|
54 |
/** |
55 |
* This was introduced as a fix to Bug , as an effort to combine the columns and |
56 |
* preference dialogs into one. It should be noted that the class can be re-used |
57 |
* or turned into a tool for column viewers in general, but with some |
58 |
* modifications. See example attached at the end of this class |
59 |
* |
60 |
* @since 3.7 |
61 |
* |
62 |
* @author Hitesh Soliwal |
63 |
* |
64 |
* @noextend This class is not intended to be subclassed by clients. |
65 |
* |
66 |
*/ |
67 |
abstract class ViewerColumnsDialog extends ViewSettingsDialog { |
68 |
|
69 |
/** The list contains columns that are currently visible in viewer */ |
70 |
private List visible; |
71 |
|
72 |
/** The list contains columns that are note shown in viewer */ |
73 |
private List nonVisible; |
74 |
|
75 |
/** |
76 |
* The number of elements to show at Max. A zero value may indicate |
77 |
* disablement of limit |
78 |
*/ |
79 |
private int limitValue; |
80 |
|
81 |
/** The message area */ |
82 |
private CLabel messageLabel; |
83 |
|
84 |
private TableViewer visibleViewer, nonVisibleViewer; |
85 |
|
86 |
private Button upButton, downButton; |
87 |
|
88 |
private Button toVisibleBtt, toNonVisibleBtt; |
89 |
|
90 |
private Text widthText, limitEditor; |
91 |
|
92 |
/** |
93 |
* A listener to validate positive integer numbers only |
94 |
*/ |
95 |
Listener postivIntTextListener = new Listener() { |
96 |
|
97 |
private String intialValue; |
98 |
|
99 |
public void handleEvent(Event event) { |
100 |
intialValue = intialValue != null ? intialValue : Integer |
101 |
.toString(0); |
102 |
intialValue = handleIntegerFieldChange(event, intialValue); |
103 |
} |
104 |
}; |
105 |
|
106 |
/** |
107 |
* Create a new instance of the receiver. |
108 |
* |
109 |
* @param parentShell |
110 |
*/ |
111 |
ViewerColumnsDialog(Shell parentShell) { |
112 |
super(parentShell); |
113 |
} |
114 |
|
115 |
/** |
116 |
* Initialize visible /non-visible columns. |
117 |
* |
118 |
* @param columnObjs |
119 |
*/ |
120 |
void setColumnsObjs(Object[] columnObjs) { |
121 |
IColumnInfoProvider columnInfo = doGetColumnInfoProvider(); |
122 |
IColumnUpdater updater = doGetColumnUpdater(); |
123 |
List visible = getVisible(); |
124 |
List nonVisible = getNonVisible(); |
125 |
visible.clear(); |
126 |
nonVisible.clear(); |
127 |
Object data = null; |
128 |
for (int i = 0; i < columnObjs.length; i++) { |
129 |
data = columnObjs[i]; |
130 |
if (columnInfo.isColumnVisible(data)) { |
131 |
updater.setColumnVisible(data, true); |
132 |
updater.setColumnIndex(data, visible.size()); |
133 |
visible.add(data); |
134 |
} else { |
135 |
updater.setColumnVisible(data, false); |
136 |
updater.setColumnIndex(data, nonVisible.size()); |
137 |
nonVisible.add(data); |
138 |
} |
139 |
} |
140 |
} |
141 |
|
142 |
/* |
143 |
* (non-Javadoc) |
144 |
* |
145 |
* @see |
146 |
* org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets |
147 |
* .Shell) |
148 |
*/ |
149 |
protected void configureShell(Shell newShell) { |
150 |
super.configureShell(newShell); |
151 |
newShell.setText(JFaceResources |
152 |
.getString("ConfigureColumnsDialog_Title")); //$NON-NLS-1$ |
153 |
} |
154 |
|
155 |
/* |
156 |
* (non-Javadoc) |
157 |
* |
158 |
* @see org.eclipse.jface.window.Window#getShellStyle() |
159 |
*/ |
160 |
protected int getShellStyle() { |
161 |
return super.getShellStyle() | SWT.RESIZE; |
162 |
} |
163 |
|
164 |
/* |
165 |
* (non-Javadoc) |
166 |
* |
167 |
* @see |
168 |
* org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets |
169 |
* .Composite) |
170 |
*/ |
171 |
protected Control createDialogArea(Composite parent) { |
172 |
|
173 |
Composite dialogArea = (Composite) super.createDialogArea(parent); |
174 |
|
175 |
dialogArea.setLayout(new GridLayout(1, true)); |
176 |
|
177 |
initializeDialogUnits(dialogArea); |
178 |
|
179 |
createMessageArea(dialogArea); |
180 |
|
181 |
createLimitArea(dialogArea); |
182 |
|
183 |
createColumnsArea(dialogArea); |
184 |
|
185 |
applyDialogFont(dialogArea); |
186 |
|
187 |
initializeDlg(); |
188 |
|
189 |
return dialogArea; |
190 |
} |
191 |
|
192 |
/** |
193 |
* |
194 |
*/ |
195 |
void initializeDlg() { |
196 |
handleStatusUdpate(IStatus.INFO, getDefaultMessage()); |
197 |
} |
198 |
|
199 |
/** |
200 |
* Create message area. |
201 |
* |
202 |
* @param parent |
203 |
*/ |
204 |
void createMessageArea(Composite parent) { |
205 |
messageLabel = new CLabel(parent, SWT.NONE); |
206 |
messageLabel.setImage(JFaceResources |
207 |
.getImage(Dialog.DLG_IMG_MESSAGE_INFO)); |
208 |
messageLabel |
209 |
.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false)); |
210 |
} |
211 |
|
212 |
/** |
213 |
* Create element limit area. |
214 |
* |
215 |
* @param parent |
216 |
*/ |
217 |
void createLimitArea(Composite parent) { |
218 |
Composite composite = new Group(parent, SWT.NONE); |
219 |
composite.setLayout(new GridLayout(2, false)); |
220 |
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
221 |
|
222 |
CLabel cLabel = new CLabel(composite, SWT.NONE); |
223 |
cLabel.setText(MarkerMessages.MarkerPreferences_VisibleItems); |
224 |
cLabel.setLayoutData(new GridData()); |
225 |
|
226 |
limitEditor = new Text(composite, SWT.BORDER); |
227 |
limitEditor.setText(Integer.toString(getLimitValue())); |
228 |
limitEditor.setLayoutData(new GridData()); |
229 |
limitEditor.addListener(SWT.FocusOut, postivIntTextListener); |
230 |
limitEditor.addListener(SWT.KeyDown, postivIntTextListener); |
231 |
limitEditor.addListener(SWT.Modify, new Listener() { |
232 |
public void handleEvent(Event event) { |
233 |
int limit = 0; |
234 |
try { |
235 |
limit = Integer.parseInt(limitEditor.getText().trim()); |
236 |
} catch (Exception e) { |
237 |
return;// ignore this one |
238 |
} |
239 |
setLimitValue(limit); |
240 |
} |
241 |
}); |
242 |
limitEditor.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
243 |
} |
244 |
|
245 |
/** |
246 |
* Create the controls to configure columns. |
247 |
* |
248 |
* @param dialogArea |
249 |
*/ |
250 |
void createColumnsArea(Composite dialogArea) { |
251 |
Group columnArea = new Group(dialogArea, SWT.NONE); |
252 |
columnArea.setLayout(new GridLayout(4, false)); |
253 |
GridData gData = new GridData(GridData.FILL_BOTH |
254 |
| GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); |
255 |
columnArea.setLayoutData(gData); |
256 |
columnArea.setText(MarkerMessages.MarkerPreferences_ColumnGroupTitle); |
257 |
|
258 |
createInvisibleTable(columnArea); |
259 |
createMoveButtons(columnArea); |
260 |
createVisibleTable(columnArea); |
261 |
createUpDownBtt(columnArea); |
262 |
createWidthArea(columnArea); |
263 |
} |
264 |
|
265 |
/** |
266 |
* The Up and Down button to change column ordering. |
267 |
* |
268 |
* @param parent |
269 |
*/ |
270 |
void createUpDownBtt(Composite parent) { |
271 |
Composite composite = new Composite(parent, SWT.NONE); |
272 |
GridLayout layout = new GridLayout(1, true); |
273 |
layout.horizontalSpacing = 0; |
274 |
layout.marginRight = -1; |
275 |
layout.marginLeft = -1; |
276 |
layout.marginWidth = 0; |
277 |
composite.setLayout(layout); |
278 |
composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL |
279 |
| GridData.VERTICAL_ALIGN_END)); |
280 |
upButton = new Button(composite, SWT.PUSH); |
281 |
upButton.setText(JFaceResources.getString("ConfigureColumnsDialog_up")); //$NON-NLS-1$ |
282 |
upButton.addListener(SWT.Selection, new Listener() { |
283 |
public void handleEvent(Event event) { |
284 |
handleUpButton(event); |
285 |
} |
286 |
}); |
287 |
upButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
288 |
upButton.setEnabled(false); |
289 |
|
290 |
downButton = new Button(composite, SWT.PUSH); |
291 |
downButton.setText(JFaceResources |
292 |
.getString("ConfigureColumnsDialog_down")); //$NON-NLS-1$ |
293 |
downButton.addListener(SWT.Selection, new Listener() { |
294 |
public void handleEvent(Event event) { |
295 |
handleDownButton(event); |
296 |
} |
297 |
}); |
298 |
downButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
299 |
downButton.setEnabled(false); |
300 |
} |
301 |
|
302 |
/** |
303 |
* Create the controls responsible to display/edit column widths. |
304 |
* |
305 |
* @param parent |
306 |
*/ |
307 |
void createWidthArea(Composite parent) { |
308 |
Label widthLabel = new Label(parent, SWT.NONE); |
309 |
widthLabel.setText(JFaceResources |
310 |
.getString("ConfigureColumnsDialog_WidthOfSelectedColumn")); //$NON-NLS-1$ |
311 |
GridData gridData = new GridData(GridData.FILL_HORIZONTAL |
312 |
| GridData.HORIZONTAL_ALIGN_END); |
313 |
gridData.horizontalSpan = 3; |
314 |
widthLabel.setLayoutData(gridData); |
315 |
|
316 |
widthText = new Text(parent, SWT.SINGLE | SWT.BORDER); |
317 |
widthText.setText(Integer.toString(0)); |
318 |
gridData = new GridData(GridData.FILL_HORIZONTAL |
319 |
| GridData.HORIZONTAL_ALIGN_CENTER); |
320 |
gridData.widthHint = convertWidthInCharsToPixels(5); |
321 |
widthText.setLayoutData(gridData); |
322 |
widthText.addListener(SWT.KeyDown, postivIntTextListener); |
323 |
widthText.addListener(SWT.FocusOut, postivIntTextListener); |
324 |
widthText.addListener(SWT.Modify, new Listener() { |
325 |
public void handleEvent(Event event) { |
326 |
if (widthText.isEnabled()) { |
327 |
int width = 0; |
328 |
try { |
329 |
width = Integer.parseInt(widthText.getText().trim()); |
330 |
} catch (Exception e) { |
331 |
return;// ignore this one |
332 |
} |
333 |
Object data = ((IStructuredSelection) visibleViewer |
334 |
.getSelection()).getFirstElement(); |
335 |
if (data != null) { |
336 |
IColumnUpdater updater = getColumnUpdater(); |
337 |
updater.setColumnWidth(data, width); |
338 |
} |
339 |
} |
340 |
} |
341 |
}); |
342 |
widthText.setText(MarkerSupportInternalUtilities.EMPTY_STRING); |
343 |
widthText.setEditable(false); |
344 |
} |
345 |
|
346 |
/** |
347 |
* Adapter to {@link IStructuredContentProvider} |
348 |
*/ |
349 |
abstract class ContentProviderAdapter implements IStructuredContentProvider { |
350 |
|
351 |
public void dispose() { |
352 |
} |
353 |
|
354 |
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
355 |
} |
356 |
} |
357 |
|
358 |
/** |
359 |
* Creates the table that lists out visible columns in the viewer |
360 |
* |
361 |
* @param parent |
362 |
*/ |
363 |
void createVisibleTable(Composite parent) { |
364 |
final Table table = new Table(parent, SWT.BORDER | SWT.MULTI); |
365 |
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); |
366 |
data.widthHint = convertWidthInCharsToPixels(30); |
367 |
data.heightHint = table.getItemHeight() * 15; |
368 |
table.setLayoutData(data); |
369 |
table.setHeaderVisible(true); |
370 |
|
371 |
final TableColumn column = new TableColumn(table, SWT.NONE); |
372 |
column.setText(MarkerMessages.MarkerPreferences_VisibleColumnsTitle); |
373 |
Listener columnResize = new Listener() { |
374 |
public void handleEvent(Event event) { |
375 |
column.setWidth(table.getClientArea().width); |
376 |
} |
377 |
}; |
378 |
table.addListener(SWT.Resize, columnResize); |
379 |
|
380 |
visibleViewer = new TableViewer(table); |
381 |
visibleViewer.setLabelProvider(doGetLabelProvider()); |
382 |
visibleViewer.setContentProvider(new ContentProviderAdapter() { |
383 |
public Object[] getElements(Object inputElement) { |
384 |
return getVisible().toArray(); |
385 |
} |
386 |
}); |
387 |
visibleViewer |
388 |
.addSelectionChangedListener(new ISelectionChangedListener() { |
389 |
public void selectionChanged(SelectionChangedEvent event) { |
390 |
handleVisibleSelection(event.getSelection()); |
391 |
} |
392 |
}); |
393 |
table.addListener(SWT.MouseDoubleClick, new Listener() { |
394 |
public void handleEvent(Event event) { |
395 |
handleToNonVisibleButton(event); |
396 |
} |
397 |
}); |
398 |
visibleViewer.setInput(this); |
399 |
} |
400 |
|
401 |
/** |
402 |
* Creates the table that lists out non-visible columns in the viewer |
403 |
* |
404 |
* @param parent |
405 |
*/ |
406 |
void createInvisibleTable(Composite parent) { |
407 |
final Table table = new Table(parent, SWT.BORDER | SWT.MULTI); |
408 |
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); |
409 |
data.widthHint = convertWidthInCharsToPixels(30); |
410 |
data.heightHint = table.getItemHeight() * 15; |
411 |
table.setLayoutData(data); |
412 |
table.setHeaderVisible(true); |
413 |
|
414 |
final TableColumn column = new TableColumn(table, SWT.NONE); |
415 |
column.setText(MarkerMessages.MarkerPreferences_HiddenColumnsTitle); |
416 |
Listener columnResize = new Listener() { |
417 |
public void handleEvent(Event event) { |
418 |
column.setWidth(table.getClientArea().width); |
419 |
} |
420 |
}; |
421 |
table.addListener(SWT.Resize, columnResize); |
422 |
|
423 |
nonVisibleViewer = new TableViewer(table); |
424 |
nonVisibleViewer.setLabelProvider(doGetLabelProvider()); |
425 |
nonVisibleViewer.setContentProvider(new ContentProviderAdapter() { |
426 |
public Object[] getElements(Object inputElement) { |
427 |
return getNonVisible().toArray(); |
428 |
} |
429 |
}); |
430 |
nonVisibleViewer |
431 |
.addSelectionChangedListener(new ISelectionChangedListener() { |
432 |
public void selectionChanged(SelectionChangedEvent event) { |
433 |
handleNonVisibleSelection(event.getSelection()); |
434 |
} |
435 |
}); |
436 |
table.addListener(SWT.MouseDoubleClick, new Listener() { |
437 |
public void handleEvent(Event event) { |
438 |
handleToVisibleButton(event); |
439 |
} |
440 |
}); |
441 |
nonVisibleViewer.setInput(this); |
442 |
} |
443 |
|
444 |
/** |
445 |
* Creates buttons for moving columns from non-visible to visible and |
446 |
* vice-versa |
447 |
* |
448 |
* @param parent |
449 |
*/ |
450 |
void createMoveButtons(Composite parent) { |
451 |
Composite bttArea = new Composite(parent, SWT.NONE); |
452 |
bttArea.setLayout(new GridLayout(1, true)); |
453 |
bttArea.setLayoutData(new GridData(GridData.FILL_VERTICAL)); |
454 |
|
455 |
toNonVisibleBtt = new Button(bttArea, SWT.PUSH); |
456 |
toNonVisibleBtt |
457 |
.setText(getDefaultOrientation() == SWT.RIGHT_TO_LEFT ? MarkerMessages.MarkerPreferences_MoveRight |
458 |
: MarkerMessages.MarkerPreferences_MoveLeft); |
459 |
toNonVisibleBtt.setLayoutData(new GridData()); |
460 |
|
461 |
toNonVisibleBtt.addListener(SWT.Selection, new Listener() { |
462 |
public void handleEvent(Event event) { |
463 |
handleToNonVisibleButton(event); |
464 |
} |
465 |
}); |
466 |
toNonVisibleBtt.setEnabled(false); |
467 |
|
468 |
toVisibleBtt = new Button(bttArea, SWT.PUSH); |
469 |
toVisibleBtt |
470 |
.setText(getDefaultOrientation() == SWT.RIGHT_TO_LEFT ? MarkerMessages.MarkerPreferences_MoveLeft |
471 |
: MarkerMessages.MarkerPreferences_MoveRight); |
472 |
toVisibleBtt.setLayoutData(new GridData()); |
473 |
toVisibleBtt.addListener(SWT.Selection, new Listener() { |
474 |
public void handleEvent(Event event) { |
475 |
handleToVisibleButton(event); |
476 |
} |
477 |
}); |
478 |
toVisibleBtt.setEnabled(false); |
479 |
} |
480 |
|
481 |
/** |
482 |
* Display the error message and an appropriate icon. |
483 |
* |
484 |
* @param messgage |
485 |
* @param severity |
486 |
*/ |
487 |
protected void handleStatusUdpate(int severity, String messgage) { |
488 |
Image image = null; |
489 |
switch (severity) { |
490 |
case IStatus.ERROR: { |
491 |
if (messgage == null) { |
492 |
messgage = getErrorMessage(); |
493 |
} |
494 |
image = getErrorImage(); |
495 |
break; |
496 |
} |
497 |
case IStatus.WARNING: { |
498 |
image = getWarningImage(); |
499 |
break; |
500 |
} |
501 |
case IStatus.OK: |
502 |
case IStatus.INFO: |
503 |
default: |
504 |
image = getInfoImage(); |
505 |
} |
506 |
messageLabel.setImage(image); |
507 |
if (messgage == null) { |
508 |
messgage = getDefaultMessage(); |
509 |
} |
510 |
if (messgage == null) { |
511 |
messgage = MarkerSupportInternalUtilities.EMPTY_STRING; |
512 |
} |
513 |
messageLabel.setText(messgage); |
514 |
} |
515 |
|
516 |
/** |
517 |
* Return the message to display when dialog is opened. |
518 |
*/ |
519 |
protected String getDefaultMessage() { |
520 |
return MarkerMessages.MarkerPreferences_ZeroOrBlankValueCanBeUsedToDisableTheLimit; |
521 |
} |
522 |
|
523 |
/** |
524 |
* @return Returns the error message to display for a wrong limit value. |
525 |
*/ |
526 |
protected String getErrorMessage() { |
527 |
return JFaceResources.getString("IntegerFieldEditor.errorMessage"); //$NON-NLS-1$ |
528 |
} |
529 |
|
530 |
/** |
531 |
*/ |
532 |
protected Image getInfoImage() { |
533 |
return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO); |
534 |
} |
535 |
|
536 |
/** |
537 |
*/ |
538 |
protected Image getWarningImage() { |
539 |
return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING); |
540 |
} |
541 |
|
542 |
/** |
543 |
*/ |
544 |
protected Image getErrorImage() { |
545 |
return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR); |
546 |
} |
547 |
|
548 |
/* |
549 |
* (non-Javadoc) |
550 |
* |
551 |
* @see org.eclipse.ui.preferences.ViewSettingsDialog#performDefaults() |
552 |
*/ |
553 |
protected void performDefaults() { |
554 |
refreshViewers(); |
555 |
super.performDefaults(); |
556 |
} |
557 |
|
558 |
/** |
559 |
* |
560 |
* @param event |
561 |
* @param intialvalue |
562 |
* @return new integer value |
563 |
*/ |
564 |
String handleIntegerFieldChange(Event event, String intialvalue) { |
565 |
Text text = (Text) event.widget; |
566 |
String value = text.getText().trim(); |
567 |
switch (event.type) { |
568 |
case SWT.KeyDown: |
569 |
if (!Character.isDigit(event.character)) { |
570 |
if (!Character.isISOControl(event.character)) { |
571 |
handleStatusUdpate(IStatus.ERROR, getErrorMessage()); |
572 |
event.doit = false; |
573 |
return intialvalue; |
574 |
} |
575 |
} |
576 |
case SWT.FocusOut: |
577 |
if (value.length() == 0) { |
578 |
value = Integer.toString(0); |
579 |
text.setText(value); |
580 |
text.selectAll(); |
581 |
handleStatusUdpate(IStatus.INFO, null); |
582 |
} else { |
583 |
try { |
584 |
Integer.parseInt(value); |
585 |
handleStatusUdpate(IStatus.INFO, null); |
586 |
} catch (Exception e) { |
587 |
value = intialvalue; |
588 |
text.setText(value); |
589 |
text.selectAll(); |
590 |
handleStatusUdpate(IStatus.ERROR, getErrorMessage()); |
591 |
event.doit = false; |
592 |
} |
593 |
} |
594 |
} |
595 |
return value; |
596 |
} |
597 |
|
598 |
/** |
599 |
* Handles a selection change in the viewer that lists out the non-visible |
600 |
* columns |
601 |
* |
602 |
* @param selection |
603 |
*/ |
604 |
void handleNonVisibleSelection(ISelection selection) { |
605 |
Object[] nvKeys = ((IStructuredSelection) selection).toArray(); |
606 |
toVisibleBtt.setEnabled(nvKeys.length > 0); |
607 |
} |
608 |
|
609 |
/** |
610 |
* Handles a selection change in the viewer that lists out the visible |
611 |
* columns. Takes care of various enablements. |
612 |
* |
613 |
* @param selection |
614 |
*/ |
615 |
void handleVisibleSelection(ISelection selection) { |
616 |
List selVCols = ((IStructuredSelection) selection).toList(); |
617 |
List allVCols = getVisible(); |
618 |
toNonVisibleBtt.setEnabled(selVCols.size() > 0 |
619 |
&& allVCols.size() > selVCols.size()); |
620 |
|
621 |
IColumnInfoProvider infoProvider = doGetColumnInfoProvider(); |
622 |
boolean moveDown = !selVCols.isEmpty(), moveUp = !selVCols.isEmpty(); |
623 |
Iterator iterator = selVCols.iterator(); |
624 |
while (iterator.hasNext()) { |
625 |
Object columnObj = iterator.next(); |
626 |
if (!infoProvider.isColumnMovable(columnObj)) { |
627 |
moveUp = false; |
628 |
moveDown = false; |
629 |
break; |
630 |
} |
631 |
int i = allVCols.indexOf(columnObj); |
632 |
if (i == 0) { |
633 |
moveUp = false; |
634 |
if (!moveDown) { |
635 |
break; |
636 |
} |
637 |
} |
638 |
if (i == (allVCols.size() - 1)) { |
639 |
moveDown = false; |
640 |
if (!moveUp) { |
641 |
break; |
642 |
} |
643 |
} |
644 |
} |
645 |
upButton.setEnabled(moveUp); |
646 |
downButton.setEnabled(moveDown); |
647 |
|
648 |
boolean edit = selVCols.size() == 1 ? infoProvider |
649 |
.isColumnResizable(selVCols.get(0)) : false; |
650 |
if (edit) { |
651 |
widthText.setText(Integer.toString(infoProvider |
652 |
.getColumnWidth(selVCols.get(0)))); |
653 |
} else { |
654 |
widthText.setText(Integer.toString(0)); |
655 |
} |
656 |
widthText.setEditable(edit); |
657 |
} |
658 |
|
659 |
/** |
660 |
* Applies to visible columns, and handles the changes in the order of |
661 |
* columns |
662 |
* |
663 |
* @param e |
664 |
* event from the button click |
665 |
*/ |
666 |
void handleDownButton(Event e) { |
667 |
IStructuredSelection selection = (IStructuredSelection) visibleViewer |
668 |
.getSelection(); |
669 |
Object[] selVCols = selection.toArray(); |
670 |
List allVCols = getVisible(); |
671 |
IColumnUpdater updater = doGetColumnUpdater(); |
672 |
for (int i = selVCols.length - 1; i >= 0; i--) { |
673 |
Object colObj = selVCols[i]; |
674 |
int index = allVCols.indexOf(colObj); |
675 |
updater.setColumnIndex(colObj, index + 1); |
676 |
allVCols.remove(index); |
677 |
allVCols.add(index + 1, colObj); |
678 |
} |
679 |
visibleViewer.refresh(); |
680 |
handleVisibleSelection(selection); |
681 |
} |
682 |
|
683 |
/** |
684 |
* Applies to visible columns, and handles the changes in the order of |
685 |
* columns |
686 |
* |
687 |
* @param e |
688 |
* event from the button click |
689 |
*/ |
690 |
void handleUpButton(Event e) { |
691 |
IStructuredSelection selection = (IStructuredSelection) visibleViewer |
692 |
.getSelection(); |
693 |
Object[] selVCols = selection.toArray(); |
694 |
List allVCols = getVisible(); |
695 |
IColumnUpdater updater = doGetColumnUpdater(); |
696 |
for (int i = 0; i < selVCols.length; i++) { |
697 |
Object colObj = selVCols[i]; |
698 |
int index = allVCols.indexOf(colObj); |
699 |
updater.setColumnIndex(colObj, index - 1); |
700 |
allVCols.remove(index); |
701 |
allVCols.add(index - 1, colObj); |
702 |
} |
703 |
visibleViewer.refresh(); |
704 |
handleVisibleSelection(selection); |
705 |
} |
706 |
|
707 |
/** |
708 |
* Moves selected columns from non-visible to visible state |
709 |
* |
710 |
* @param e |
711 |
* event from the button click |
712 |
*/ |
713 |
void handleToVisibleButton(Event e) { |
714 |
IStructuredSelection selection = (IStructuredSelection) nonVisibleViewer |
715 |
.getSelection(); |
716 |
List selVCols = selection.toList(); |
717 |
List nonVisible = getNonVisible(); |
718 |
nonVisible.removeAll(selVCols); |
719 |
|
720 |
List list = getVisible(); |
721 |
list.addAll(selVCols); |
722 |
|
723 |
updateVisibility(selVCols, true); |
724 |
updateIndices(getVisible()); |
725 |
updateIndices(getNonVisible()); |
726 |
|
727 |
visibleViewer.refresh(); |
728 |
visibleViewer.setSelection(selection); |
729 |
nonVisibleViewer.refresh(); |
730 |
handleVisibleSelection(selection); |
731 |
handleNonVisibleSelection(nonVisibleViewer.getSelection()); |
732 |
} |
733 |
|
734 |
/** |
735 |
* Moves selected columns from visible to non-visible state |
736 |
* |
737 |
* @param e |
738 |
* event from the button click |
739 |
*/ |
740 |
protected void handleToNonVisibleButton(Event e) { |
741 |
if (getVisible().size() <= 1) { |
742 |
handleStatusUdpate(IStatus.INFO, |
743 |
MarkerMessages.MarkerPreferences_AtLeastOneVisibleColumn); |
744 |
return; |
745 |
} |
746 |
IStructuredSelection selection = (IStructuredSelection) visibleViewer |
747 |
.getSelection(); |
748 |
List selVCols = selection.toList(); |
749 |
getVisible().removeAll(selVCols); |
750 |
getNonVisible().addAll(selVCols); |
751 |
|
752 |
updateVisibility(selVCols, false); |
753 |
updateIndices(getVisible()); |
754 |
updateIndices(getNonVisible()); |
755 |
|
756 |
nonVisibleViewer.refresh(); |
757 |
nonVisibleViewer.setSelection(selection); |
758 |
visibleViewer.refresh(); |
759 |
handleVisibleSelection(visibleViewer.getSelection()); |
760 |
handleNonVisibleSelection(nonVisibleViewer.getSelection()); |
761 |
handleStatusUdpate(IStatus.INFO, getDefaultMessage()); |
762 |
} |
763 |
|
764 |
void updateIndices(List list) { |
765 |
ListIterator iterator = list.listIterator(); |
766 |
IColumnUpdater updater = doGetColumnUpdater(); |
767 |
while (iterator.hasNext()) { |
768 |
updater.setColumnIndex(iterator.next(), iterator.previousIndex()); |
769 |
} |
770 |
} |
771 |
|
772 |
void updateVisibility(List list, boolean visibility) { |
773 |
IColumnUpdater updater = doGetColumnUpdater(); |
774 |
Iterator iterator = list.iterator(); |
775 |
while (iterator.hasNext()) { |
776 |
updater.setColumnVisible(iterator.next(), visibility); |
777 |
} |
778 |
} |
779 |
|
780 |
/** |
781 |
* Updates the UI based on values of the variable |
782 |
*/ |
783 |
void refreshViewers() { |
784 |
if (limitEditor != null) { |
785 |
limitEditor.setText(Integer.toString(getLimitValue())); |
786 |
} |
787 |
if (nonVisibleViewer != null) { |
788 |
nonVisibleViewer.refresh(); |
789 |
} |
790 |
if (visibleViewer != null) { |
791 |
visibleViewer.refresh(); |
792 |
} |
793 |
} |
794 |
|
795 |
/* |
796 |
* (non-Javadoc) |
797 |
* |
798 |
* @see org.eclipse.jface.dialogs.Dialog#isResizable() |
799 |
*/ |
800 |
protected boolean isResizable() { |
801 |
return true; |
802 |
} |
803 |
|
804 |
/* |
805 |
* (non-Javadoc) |
806 |
* |
807 |
* @see org.eclipse.jface.dialogs.Dialog#okPressed() |
808 |
*/ |
809 |
protected void okPressed() { |
810 |
super.okPressed(); |
811 |
} |
812 |
|
813 |
/** |
814 |
* @return Returns the limitValue. |
815 |
*/ |
816 |
public int getLimitValue() { |
817 |
return limitValue; |
818 |
} |
819 |
|
820 |
/** |
821 |
* @param limitValue |
822 |
* The limitValue to set. |
823 |
*/ |
824 |
void setLimitValue(int limitValue) { |
825 |
this.limitValue = limitValue; |
826 |
} |
827 |
|
828 |
/** |
829 |
* @return List of visible columns |
830 |
*/ |
831 |
public List getVisible() { |
832 |
if (visible == null) { |
833 |
visible = new ArrayList(); |
834 |
} |
835 |
return visible; |
836 |
} |
837 |
|
838 |
/** |
839 |
* @return List of non-visible columns |
840 |
*/ |
841 |
public List getNonVisible() { |
842 |
if (nonVisible == null) { |
843 |
nonVisible = new ArrayList(); |
844 |
} |
845 |
return nonVisible; |
846 |
} |
847 |
|
848 |
/** |
849 |
* An adapter class to {@link ITableLabelProvider} |
850 |
* |
851 |
*/ |
852 |
class TableLabelProvider extends LabelProvider implements |
853 |
ITableLabelProvider { |
854 |
public Image getColumnImage(Object element, int columnIndex) { |
855 |
return null; |
856 |
} |
857 |
|
858 |
public String getColumnText(Object element, int columnIndex) { |
859 |
return getText(element); |
860 |
} |
861 |
} |
862 |
|
863 |
/** |
864 |
* Internal helper to @see {@link ViewerColumnsDialog#getLabelProvider()} |
865 |
*/ |
866 |
ITableLabelProvider doGetLabelProvider() { |
867 |
return getLabelProvider(); |
868 |
} |
869 |
|
870 |
/** |
871 |
* The tables-columns need to be displayed appropriately. The supplied |
872 |
* column objects are adapted to text and image as dictacted by this |
873 |
* {@link ITableLabelProvider} |
874 |
*/ |
875 |
protected abstract ITableLabelProvider getLabelProvider(); |
876 |
|
877 |
/** |
878 |
* Internal helper to @see |
879 |
* {@link ViewerColumnsDialog#getColumnInfoProvider()} |
880 |
*/ |
881 |
IColumnInfoProvider doGetColumnInfoProvider() { |
882 |
return getColumnInfoProvider(); |
883 |
} |
884 |
|
885 |
/** |
886 |
* To configure the columns we need further information. The supplied column |
887 |
* objects are adapted for its properties via {@link IColumnInfoProvider} |
888 |
*/ |
889 |
protected abstract IColumnInfoProvider getColumnInfoProvider(); |
890 |
|
891 |
/** |
892 |
* Internal helper to @see {@link ViewerColumnsDialog#getColumnUpdater()} |
893 |
*/ |
894 |
IColumnUpdater doGetColumnUpdater() { |
895 |
return getColumnUpdater(); |
896 |
} |
897 |
|
898 |
/** |
899 |
* To configure properties/order of the columns is achieved via |
900 |
* {@link IColumnUpdater} |
901 |
*/ |
902 |
protected abstract IColumnUpdater getColumnUpdater(); |
903 |
|
904 |
/** |
905 |
* Update various aspects of a columns from a viewer such |
906 |
* {@link TableViewer} |
907 |
*/ |
908 |
public interface IColumnInfoProvider { |
909 |
|
910 |
/** |
911 |
* Get corresponding index for the column |
912 |
* |
913 |
* @param columnObj |
914 |
*/ |
915 |
public int getColumnIndex(Object columnObj); |
916 |
|
917 |
/** |
918 |
* Get the width of the column |
919 |
* |
920 |
* @param columnObj |
921 |
*/ |
922 |
public int getColumnWidth(Object columnObj); |
923 |
|
924 |
/** |
925 |
* Returns true if the column represented by parameters is showing in |
926 |
* the viewer |
927 |
* |
928 |
* @param columnObj |
929 |
*/ |
930 |
public boolean isColumnVisible(Object columnObj); |
931 |
|
932 |
/** |
933 |
* Returns true if the column represented by parameters is configured as |
934 |
* movable |
935 |
* |
936 |
* @param columnObj |
937 |
*/ |
938 |
public boolean isColumnMovable(Object columnObj); |
939 |
|
940 |
/** |
941 |
* Returns true if the column represented by parameters is configured as |
942 |
* resizable |
943 |
* |
944 |
* @param columnObj |
945 |
*/ |
946 |
public boolean isColumnResizable(Object columnObj); |
947 |
|
948 |
} |
949 |
|
950 |
/** |
951 |
* Update various aspects of a columns from a viewer such |
952 |
* {@link TableViewer} |
953 |
*/ |
954 |
public interface IColumnUpdater { |
955 |
|
956 |
/** |
957 |
* Set the column represented by parameters as visible |
958 |
* |
959 |
* @param columnObj |
960 |
* @param visible |
961 |
*/ |
962 |
public void setColumnVisible(Object columnObj, boolean visible); |
963 |
|
964 |
/** |
965 |
* Dummy method - more a result of symmetry |
966 |
* |
967 |
* @param columnObj |
968 |
* @param movable |
969 |
*/ |
970 |
public void setColumnMovable(Object columnObj, boolean movable); |
971 |
|
972 |
/** |
973 |
* Call back to notify change in the index of the column represented by |
974 |
* columnObj |
975 |
* |
976 |
* @param columnObj |
977 |
* @param index |
978 |
*/ |
979 |
public void setColumnIndex(Object columnObj, int index); |
980 |
|
981 |
/** |
982 |
* Dummy method - more a result of symmetry |
983 |
* |
984 |
* @param columnObj |
985 |
* @param resizable |
986 |
*/ |
987 |
public void setColumnResizable(Object columnObj, boolean resizable); |
988 |
|
989 |
/** |
990 |
* Call back to notify change in the width of the column represented by |
991 |
* columnObj |
992 |
* |
993 |
* @param columnObj |
994 |
* @param newWidth |
995 |
*/ |
996 |
public void setColumnWidth(Object columnObj, int newWidth); |
997 |
|
998 |
} |
999 |
|
1000 |
// ////////////////////////////////////////////////////////////////////////////////// |
1001 |
/** |
1002 |
* Ignore the class below as it is simply meant to test the above. I intend |
1003 |
* to retain this for a while. |
1004 |
*/ |
1005 |
static class TestData { |
1006 |
|
1007 |
final Object key; |
1008 |
|
1009 |
final int keyIndex; |
1010 |
|
1011 |
int newIndex, width; |
1012 |
|
1013 |
boolean visibility, movable, resizable; |
1014 |
|
1015 |
TestData(Object key, int currIndex) { |
1016 |
this.key = key; |
1017 |
this.keyIndex = currIndex; |
1018 |
} |
1019 |
|
1020 |
public int hashCode() { |
1021 |
final int prime = 31; |
1022 |
int result = 1; |
1023 |
result = prime * result + ((key == null) ? 0 : key.hashCode()); |
1024 |
result = prime * result + keyIndex; |
1025 |
return result; |
1026 |
} |
1027 |
|
1028 |
public boolean equals(Object obj) { |
1029 |
if (this == obj) { |
1030 |
return true; |
1031 |
} |
1032 |
if (obj == null) { |
1033 |
return false; |
1034 |
} |
1035 |
if (!(obj instanceof TestData)) { |
1036 |
return false; |
1037 |
} |
1038 |
TestData other = (TestData) obj; |
1039 |
if (key == null) { |
1040 |
if (other.key != null) { |
1041 |
return false; |
1042 |
} |
1043 |
} else if (!key.equals(other.key)) { |
1044 |
return false; |
1045 |
} |
1046 |
if (keyIndex != other.keyIndex) { |
1047 |
return false; |
1048 |
} |
1049 |
return true; |
1050 |
} |
1051 |
|
1052 |
public String toString() { |
1053 |
return key.toString(); |
1054 |
} |
1055 |
|
1056 |
private static ViewerColumnsDialog getColumnsDialog(Shell shell, |
1057 |
final TestData[] colums) { |
1058 |
ViewerColumnsDialog dialog = new ViewerColumnsDialog(shell) { |
1059 |
|
1060 |
protected IColumnInfoProvider getColumnInfoProvider() { |
1061 |
return getInfoProvider(colums); |
1062 |
} |
1063 |
|
1064 |
protected ITableLabelProvider getLabelProvider() { |
1065 |
return new TableLabelProvider(); |
1066 |
} |
1067 |
|
1068 |
protected IColumnUpdater getColumnUpdater() { |
1069 |
return getUpdater(colums); |
1070 |
} |
1071 |
}; |
1072 |
dialog.setColumnsObjs(colums); |
1073 |
return dialog; |
1074 |
} |
1075 |
|
1076 |
private static IColumnUpdater getUpdater(final TestData[] data) { |
1077 |
return new IColumnUpdater() { |
1078 |
|
1079 |
public void setColumnWidth(Object columnObj, int newWidth) { |
1080 |
((TestData) columnObj).width = newWidth; |
1081 |
} |
1082 |
|
1083 |
public void setColumnVisible(Object columnObj, boolean visible) { |
1084 |
((TestData) columnObj).visibility = visible; |
1085 |
} |
1086 |
|
1087 |
public void setColumnResizable(Object columnObj, |
1088 |
boolean resizable) { |
1089 |
|
1090 |
} |
1091 |
|
1092 |
public void setColumnMovable(Object columnObj, boolean movable) { |
1093 |
((TestData) columnObj).movable = movable; |
1094 |
|
1095 |
} |
1096 |
|
1097 |
public void setColumnIndex(Object columnObj, int index) { |
1098 |
((TestData) columnObj).newIndex = index; |
1099 |
} |
1100 |
}; |
1101 |
} |
1102 |
|
1103 |
private static IColumnInfoProvider getInfoProvider( |
1104 |
final TestData[] colData) { |
1105 |
return new IColumnInfoProvider() { |
1106 |
|
1107 |
public boolean isColumnVisible(Object columnObj) { |
1108 |
return ((TestData) columnObj).visibility; |
1109 |
} |
1110 |
|
1111 |
public boolean isColumnResizable(Object columnObj) { |
1112 |
return ((TestData) columnObj).resizable; |
1113 |
} |
1114 |
|
1115 |
public boolean isColumnMovable(Object columnObj) { |
1116 |
return ((TestData) columnObj).movable; |
1117 |
} |
1118 |
|
1119 |
public int getColumnWidth(Object columnObj) { |
1120 |
return ((TestData) columnObj).width; |
1121 |
} |
1122 |
|
1123 |
public int getColumnIndex(Object columnObj) { |
1124 |
return ((TestData) columnObj).newIndex; |
1125 |
} |
1126 |
}; |
1127 |
} |
1128 |
|
1129 |
private static TestData[] genData(int count) { |
1130 |
String[] cols = new String[count]; |
1131 |
for (int i = 0; i < cols.length; i++) { |
1132 |
cols[i] = new String("Column-" + (i + 1)); //$NON-NLS-1$ |
1133 |
} |
1134 |
Random random = new Random(); |
1135 |
|
1136 |
boolean[] visibility = new boolean[cols.length]; |
1137 |
Arrays.fill(visibility, true); |
1138 |
int ranInt = random.nextInt() % cols.length; |
1139 |
for (int i = 0; i < ranInt; i++) { |
1140 |
visibility[random.nextInt(ranInt)] = false; |
1141 |
} |
1142 |
|
1143 |
boolean[] resizable = new boolean[cols.length]; |
1144 |
Arrays.fill(resizable, true); |
1145 |
ranInt = random.nextInt() % cols.length; |
1146 |
for (int i = 0; i < ranInt; i++) { |
1147 |
resizable[random.nextInt(ranInt)] = false; |
1148 |
} |
1149 |
|
1150 |
boolean[] movable = new boolean[cols.length]; |
1151 |
Arrays.fill(movable, true); |
1152 |
ranInt = random.nextInt() % cols.length; |
1153 |
for (int i = 0; i < ranInt; i++) { |
1154 |
movable[random.nextInt(ranInt)] = false; |
1155 |
} |
1156 |
|
1157 |
int[] widths = new int[cols.length]; |
1158 |
Arrays.fill(widths, 100); |
1159 |
return TestData.generateColumnsData(cols, visibility, resizable, |
1160 |
movable, widths); |
1161 |
} |
1162 |
|
1163 |
public static TestData[] generateColumnsData(Object[] keys, |
1164 |
boolean[] visibility, boolean[] resizable, boolean[] movable, |
1165 |
int[] widths) { |
1166 |
TestData[] colData = new TestData[keys.length]; |
1167 |
int m = 0, n = 0; |
1168 |
for (int i = 0; i < colData.length; i++) { |
1169 |
TestData data = new TestData(keys[i], i); |
1170 |
data.visibility = visibility[i]; |
1171 |
data.resizable = resizable[i]; |
1172 |
data.movable = movable[i]; |
1173 |
data.width = widths[i]; |
1174 |
if (data.visibility) { |
1175 |
data.newIndex = m++; |
1176 |
} else { |
1177 |
data.newIndex = n++; |
1178 |
} |
1179 |
colData[i] = data; |
1180 |
} |
1181 |
return colData; |
1182 |
} |
1183 |
|
1184 |
/** |
1185 |
* Demo |
1186 |
* |
1187 |
* @param args |
1188 |
*/ |
1189 |
public static void main(String[] args) { |
1190 |
Display display = new Display(); |
1191 |
final Shell shell = new Shell(display); |
1192 |
shell.setLayout(new FillLayout()); |
1193 |
ViewerColumnsDialog dialog = getColumnsDialog(shell, genData(100)); |
1194 |
dialog.open(); |
1195 |
shell.dispose(); |
1196 |
while (!shell.isDisposed()) { |
1197 |
if (!display.readAndDispatch()) { |
1198 |
display.sleep(); |
1199 |
} |
1200 |
} |
1201 |
display.dispose(); |
1202 |
|
1203 |
} |
1204 |
|
1205 |
} |
1206 |
|
1207 |
// ////////////////////////////////////////////////////////////////////////////////// |
1208 |
} |