001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.refactoring;
011:
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.Collections;
015: import java.util.Iterator;
016: import java.util.List;
017:
018: import org.eclipse.core.runtime.Assert;
019:
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.events.KeyAdapter;
022: import org.eclipse.swt.events.KeyEvent;
023: import org.eclipse.swt.events.SelectionAdapter;
024: import org.eclipse.swt.events.SelectionEvent;
025: import org.eclipse.swt.events.TraverseEvent;
026: import org.eclipse.swt.events.TraverseListener;
027: import org.eclipse.swt.graphics.Font;
028: import org.eclipse.swt.graphics.Image;
029: import org.eclipse.swt.layout.GridData;
030: import org.eclipse.swt.layout.GridLayout;
031: import org.eclipse.swt.widgets.Button;
032: import org.eclipse.swt.widgets.Composite;
033: import org.eclipse.swt.widgets.Label;
034: import org.eclipse.swt.widgets.Table;
035: import org.eclipse.swt.widgets.TableColumn;
036: import org.eclipse.swt.widgets.TableItem;
037: import org.eclipse.swt.widgets.Text;
038:
039: import org.eclipse.jface.contentassist.SubjectControlContentAssistant;
040: import org.eclipse.jface.resource.JFaceResources;
041: import org.eclipse.jface.viewers.ColumnWeightData;
042: import org.eclipse.jface.viewers.ICellModifier;
043: import org.eclipse.jface.viewers.ISelection;
044: import org.eclipse.jface.viewers.ISelectionChangedListener;
045: import org.eclipse.jface.viewers.IStructuredContentProvider;
046: import org.eclipse.jface.viewers.IStructuredSelection;
047: import org.eclipse.jface.viewers.ITableFontProvider;
048: import org.eclipse.jface.viewers.ITableLabelProvider;
049: import org.eclipse.jface.viewers.LabelProvider;
050: import org.eclipse.jface.viewers.SelectionChangedEvent;
051: import org.eclipse.jface.viewers.StructuredSelection;
052: import org.eclipse.jface.viewers.TableViewer;
053: import org.eclipse.jface.viewers.Viewer;
054:
055: import org.eclipse.ui.contentassist.ContentAssistHandler;
056:
057: import org.eclipse.jdt.core.IJavaProject;
058:
059: import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
060: import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo;
061: import org.eclipse.jdt.internal.corext.refactoring.StubTypeContext;
062:
063: import org.eclipse.jdt.internal.ui.dialogs.TableTextCellEditor;
064: import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler;
065: import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
066: import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;
067: import org.eclipse.jdt.internal.ui.refactoring.contentassist.VariableNamesProcessor;
068: import org.eclipse.jdt.internal.ui.util.SWTUtil;
069: import org.eclipse.jdt.internal.ui.util.TableLayoutComposite;
070:
071: /**
072: * A special control to edit and reorder method parameters.
073: */
074: public class ChangeParametersControl extends Composite {
075:
076: public static class Mode {
077: private final String fName;
078:
079: private Mode(String name) {
080: fName = name;
081: }
082:
083: public static final Mode EXTRACT_METHOD = new Mode(
084: "EXTRACT_METHOD"); //$NON-NLS-1$
085: public static final Mode CHANGE_METHOD_SIGNATURE = new Mode(
086: "CHANGE_METHOD_SIGNATURE"); //$NON-NLS-1$
087: public static final Mode INTRODUCE_PARAMETER = new Mode(
088: "INTRODUCE_PARAMETER"); //$NON-NLS-1$
089:
090: public String toString() {
091: return fName;
092: }
093:
094: public boolean canChangeTypes() {
095: return this == CHANGE_METHOD_SIGNATURE;
096: }
097:
098: public boolean canAddParameters() {
099: return this == Mode.CHANGE_METHOD_SIGNATURE;
100: }
101:
102: public boolean canChangeDefault() {
103: return this == Mode.CHANGE_METHOD_SIGNATURE;
104: }
105: }
106:
107: private static class ParameterInfoContentProvider implements
108: IStructuredContentProvider {
109: public Object[] getElements(Object inputElement) {
110: return removeMarkedAsDeleted((List) inputElement);
111: }
112:
113: private ParameterInfo[] removeMarkedAsDeleted(List paramInfos) {
114: List result = new ArrayList(paramInfos.size());
115: for (Iterator iter = paramInfos.iterator(); iter.hasNext();) {
116: ParameterInfo info = (ParameterInfo) iter.next();
117: if (!info.isDeleted())
118: result.add(info);
119: }
120: return (ParameterInfo[]) result
121: .toArray(new ParameterInfo[result.size()]);
122: }
123:
124: public void dispose() {
125: // do nothing
126: }
127:
128: public void inputChanged(Viewer viewer, Object oldInput,
129: Object newInput) {
130: // do nothing
131: }
132: }
133:
134: private static class ParameterInfoLabelProvider extends
135: LabelProvider implements ITableLabelProvider,
136: ITableFontProvider {
137: public Image getColumnImage(Object element, int columnIndex) {
138: return null;
139: }
140:
141: public String getColumnText(Object element, int columnIndex) {
142: ParameterInfo info = (ParameterInfo) element;
143: switch (columnIndex) {
144: case TYPE_PROP:
145: return info.getNewTypeName();
146: case NEWNAME_PROP:
147: return info.getNewName();
148: case DEFAULT_PROP:
149: if (info.isAdded())
150: return info.getDefaultValue();
151: else
152: return "-"; //$NON-NLS-1$
153: default:
154: throw new IllegalArgumentException(columnIndex
155: + ": " + element); //$NON-NLS-1$
156: }
157: }
158:
159: public Font getFont(Object element, int columnIndex) {
160: ParameterInfo info = (ParameterInfo) element;
161: if (info.isAdded())
162: return JFaceResources.getFontRegistry().getBold(
163: JFaceResources.DIALOG_FONT);
164: else
165: return null;
166: }
167: }
168:
169: private class ParametersCellModifier implements ICellModifier {
170: public boolean canModify(Object element, String property) {
171: Assert.isTrue(element instanceof ParameterInfo);
172: if (property.equals(PROPERTIES[TYPE_PROP]))
173: return fMode.canChangeTypes();
174: else if (property.equals(PROPERTIES[NEWNAME_PROP]))
175: return true;
176: else if (property.equals(PROPERTIES[DEFAULT_PROP]))
177: return (((ParameterInfo) element).isAdded());
178: Assert.isTrue(false);
179: return false;
180: }
181:
182: public Object getValue(Object element, String property) {
183: Assert.isTrue(element instanceof ParameterInfo);
184: if (property.equals(PROPERTIES[TYPE_PROP]))
185: return ((ParameterInfo) element).getNewTypeName();
186: else if (property.equals(PROPERTIES[NEWNAME_PROP]))
187: return ((ParameterInfo) element).getNewName();
188: else if (property.equals(PROPERTIES[DEFAULT_PROP]))
189: return ((ParameterInfo) element).getDefaultValue();
190: Assert.isTrue(false);
191: return null;
192: }
193:
194: public void modify(Object element, String property, Object value) {
195: if (element instanceof TableItem)
196: element = ((TableItem) element).getData();
197: if (!(element instanceof ParameterInfo))
198: return;
199: boolean unchanged;
200: ParameterInfo parameterInfo = (ParameterInfo) element;
201: if (property.equals(PROPERTIES[NEWNAME_PROP])) {
202: unchanged = parameterInfo.getNewName().equals(value);
203: parameterInfo.setNewName((String) value);
204: } else if (property.equals(PROPERTIES[DEFAULT_PROP])) {
205: unchanged = parameterInfo.getDefaultValue().equals(
206: value);
207: parameterInfo.setDefaultValue((String) value);
208: } else if (property.equals(PROPERTIES[TYPE_PROP])) {
209: unchanged = parameterInfo.getNewTypeName()
210: .equals(value);
211: parameterInfo.setNewTypeName((String) value);
212: } else {
213: throw new IllegalStateException();
214: }
215: if (!unchanged) {
216: ChangeParametersControl.this .fListener
217: .parameterChanged(parameterInfo);
218: ChangeParametersControl.this .fTableViewer.update(
219: parameterInfo, new String[] { property });
220: }
221: }
222: }
223:
224: private static final String[] PROPERTIES = {
225: "type", "new", "default" }; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-3$
226: private static final int TYPE_PROP = 0;
227: private static final int NEWNAME_PROP = 1;
228: private static final int DEFAULT_PROP = 2;
229:
230: private static final int ROW_COUNT = 7;
231:
232: private final Mode fMode;
233: private final IParameterListChangeListener fListener;
234: private List fParameterInfos;
235: private final StubTypeContext fTypeContext;
236: private final String[] fParamNameProposals;
237: private ContentAssistHandler fNameContentAssistHandler;
238:
239: private TableViewer fTableViewer;
240: private Button fUpButton;
241: private Button fDownButton;
242: private Button fEditButton;
243: private Button fAddButton;
244: private Button fRemoveButton;
245:
246: public ChangeParametersControl(Composite parent, int style,
247: String label, IParameterListChangeListener listener,
248: Mode mode, StubTypeContext typeContext) {
249: this (parent, style, label, listener, mode, typeContext,
250: new String[0]);
251: }
252:
253: public ChangeParametersControl(Composite parent, int style,
254: String label, IParameterListChangeListener listener,
255: Mode mode) {
256: this (parent, style, label, listener, mode, null, new String[0]);
257: }
258:
259: public ChangeParametersControl(Composite parent, int style,
260: String label, IParameterListChangeListener listener,
261: Mode mode, String[] paramNameProposals) {
262: this (parent, style, label, listener, mode, null,
263: paramNameProposals);
264: }
265:
266: /**
267: * @param label the label before the table or <code>null</code>
268: * @param typeContext the package in which to complete types
269: */
270: private ChangeParametersControl(Composite parent, int style,
271: String label, IParameterListChangeListener listener,
272: Mode mode, StubTypeContext typeContext,
273: String[] paramNameProposals) {
274: super (parent, style);
275: Assert.isNotNull(listener);
276: fListener = listener;
277: fMode = mode;
278: fTypeContext = typeContext;
279: fParamNameProposals = paramNameProposals;
280:
281: GridLayout layout = new GridLayout();
282: layout.numColumns = 2;
283: layout.marginWidth = 0;
284: layout.marginHeight = 0;
285: setLayout(layout);
286:
287: if (label != null) {
288: Label tableLabel = new Label(this , SWT.NONE);
289: GridData labelGd = new GridData();
290: labelGd.horizontalSpan = 2;
291: tableLabel.setLayoutData(labelGd);
292: tableLabel.setText(label);
293: }
294:
295: createParameterList(this );
296: createButtonComposite(this );
297: }
298:
299: public void setInput(List parameterInfos) {
300: Assert.isNotNull(parameterInfos);
301: fParameterInfos = parameterInfos;
302: fTableViewer.setInput(fParameterInfos);
303: if (fParameterInfos.size() > 0)
304: fTableViewer.setSelection(new StructuredSelection(
305: fParameterInfos.get(0)));
306: }
307:
308: public void editParameter(ParameterInfo info) {
309: fTableViewer.getControl().setFocus();
310: if (!info.isDeleted()) {
311: fTableViewer.setSelection(new StructuredSelection(info),
312: true);
313: updateButtonsEnabledState();
314: editColumnOrNextPossible(NEWNAME_PROP);
315: return;
316: }
317: }
318:
319: // ---- Parameter table -----------------------------------------------------------------------------------
320:
321: private void createParameterList(Composite parent) {
322: TableLayoutComposite layouter = new TableLayoutComposite(
323: parent, SWT.NONE);
324: addColumnLayoutData(layouter);
325:
326: final Table table = new Table(layouter, SWT.MULTI | SWT.BORDER
327: | SWT.FULL_SELECTION);
328: table.setHeaderVisible(true);
329: table.setLinesVisible(true);
330: TableColumn tc;
331: tc = new TableColumn(table, SWT.NONE, TYPE_PROP);
332: tc.setResizable(true);
333: tc
334: .setText(RefactoringMessages.ChangeParametersControl_table_type);
335:
336: tc = new TableColumn(table, SWT.NONE, NEWNAME_PROP);
337: tc.setResizable(true);
338: tc
339: .setText(RefactoringMessages.ChangeParametersControl_table_name);
340:
341: if (fMode.canChangeDefault()) {
342: tc = new TableColumn(table, SWT.NONE, DEFAULT_PROP);
343: tc.setResizable(true);
344: tc
345: .setText(RefactoringMessages.ChangeParametersControl_table_defaultValue);
346: }
347:
348: GridData gd = new GridData(GridData.FILL_BOTH);
349: gd.heightHint = SWTUtil.getTableHeightHint(table, ROW_COUNT);
350: gd.widthHint = 40;
351: layouter.setLayoutData(gd);
352:
353: fTableViewer = new TableViewer(table);
354: fTableViewer.setUseHashlookup(true);
355: fTableViewer
356: .setContentProvider(new ParameterInfoContentProvider());
357: fTableViewer.setLabelProvider(new ParameterInfoLabelProvider());
358: fTableViewer
359: .addSelectionChangedListener(new ISelectionChangedListener() {
360: public void selectionChanged(
361: SelectionChangedEvent event) {
362: updateButtonsEnabledState();
363: }
364: });
365:
366: table.addTraverseListener(new TraverseListener() {
367: public void keyTraversed(TraverseEvent e) {
368: if (e.detail == SWT.TRAVERSE_RETURN
369: && e.stateMask == SWT.NONE) {
370: editColumnOrNextPossible(0);
371: e.detail = SWT.TRAVERSE_NONE;
372: }
373: }
374: });
375: table.addKeyListener(new KeyAdapter() {
376: public void keyPressed(KeyEvent e) {
377: if (e.keyCode == SWT.F2 && e.stateMask == SWT.NONE) {
378: editColumnOrNextPossible(0);
379: e.doit = false;
380: }
381: }
382: });
383:
384: addCellEditors();
385: }
386:
387: private void editColumnOrNextPossible(int column) {
388: ParameterInfo[] selected = getSelectedElements();
389: if (selected.length != 1)
390: return;
391: int nextColumn = column;
392: do {
393: fTableViewer.editElement(selected[0], nextColumn);
394: if (fTableViewer.isCellEditorActive())
395: return;
396: nextColumn = nextColumn(nextColumn);
397: } while (nextColumn != column);
398: }
399:
400: private void editColumnOrPrevPossible(int column) {
401: ParameterInfo[] selected = getSelectedElements();
402: if (selected.length != 1)
403: return;
404: int prevColumn = column;
405: do {
406: fTableViewer.editElement(selected[0], prevColumn);
407: if (fTableViewer.isCellEditorActive())
408: return;
409: prevColumn = prevColumn(prevColumn);
410: } while (prevColumn != column);
411: }
412:
413: private int nextColumn(int column) {
414: return (column >= getTable().getColumnCount() - 1) ? 0
415: : column + 1;
416: }
417:
418: private int prevColumn(int column) {
419: return (column <= 0) ? getTable().getColumnCount() - 1
420: : column - 1;
421: }
422:
423: private void addColumnLayoutData(TableLayoutComposite layouter) {
424: if (fMode.canChangeDefault()) {
425: layouter.addColumnData(new ColumnWeightData(33, true));
426: layouter.addColumnData(new ColumnWeightData(33, true));
427: layouter.addColumnData(new ColumnWeightData(34, true));
428: } else {
429: layouter.addColumnData(new ColumnWeightData(50, true));
430: layouter.addColumnData(new ColumnWeightData(50, true));
431: }
432: }
433:
434: private ParameterInfo[] getSelectedElements() {
435: ISelection selection = fTableViewer.getSelection();
436: if (selection == null)
437: return new ParameterInfo[0];
438:
439: if (!(selection instanceof IStructuredSelection))
440: return new ParameterInfo[0];
441:
442: List selected = ((IStructuredSelection) selection).toList();
443: return (ParameterInfo[]) selected
444: .toArray(new ParameterInfo[selected.size()]);
445: }
446:
447: // ---- Button bar --------------------------------------------------------------------------------------
448:
449: private void createButtonComposite(Composite parent) {
450: Composite buttonComposite = new Composite(parent, SWT.NONE);
451: buttonComposite.setLayoutData(new GridData(
452: GridData.FILL_VERTICAL));
453: GridLayout gl = new GridLayout();
454: gl.marginHeight = 0;
455: gl.marginWidth = 0;
456: buttonComposite.setLayout(gl);
457:
458: if (fMode.canAddParameters())
459: fAddButton = createAddButton(buttonComposite);
460:
461: fEditButton = createEditButton(buttonComposite);
462:
463: if (fMode.canAddParameters())
464: fRemoveButton = createRemoveButton(buttonComposite);
465:
466: if (buttonComposite.getChildren().length != 0)
467: addSpacer(buttonComposite);
468:
469: fUpButton = createButton(
470: buttonComposite,
471: RefactoringMessages.ChangeParametersControl_buttons_move_up,
472: true);
473: fDownButton = createButton(
474: buttonComposite,
475: RefactoringMessages.ChangeParametersControl_buttons_move_down,
476: false);
477:
478: updateButtonsEnabledState();
479: }
480:
481: private void addSpacer(Composite parent) {
482: Label label = new Label(parent, SWT.NONE);
483: GridData gd = new GridData(GridData.FILL_HORIZONTAL);
484: gd.heightHint = 5;
485: label.setLayoutData(gd);
486: }
487:
488: private void updateButtonsEnabledState() {
489: fUpButton.setEnabled(canMove(true));
490: fDownButton.setEnabled(canMove(false));
491: if (fEditButton != null)
492: fEditButton.setEnabled(getTableSelectionCount() == 1);
493: if (fAddButton != null)
494: fAddButton.setEnabled(true);
495: if (fRemoveButton != null)
496: fRemoveButton.setEnabled(getTableSelectionCount() != 0);
497: }
498:
499: private int getTableSelectionCount() {
500: return getTable().getSelectionCount();
501: }
502:
503: private int getTableItemCount() {
504: return getTable().getItemCount();
505: }
506:
507: private Table getTable() {
508: return fTableViewer.getTable();
509: }
510:
511: private Button createEditButton(Composite buttonComposite) {
512: Button button = new Button(buttonComposite, SWT.PUSH);
513: button
514: .setText(RefactoringMessages.ChangeParametersControl_buttons_edit);
515: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
516: SWTUtil.setButtonDimensionHint(button);
517: button.addSelectionListener(new SelectionAdapter() {
518: public void widgetSelected(SelectionEvent e) {
519: try {
520: ParameterInfo[] selected = getSelectedElements();
521: Assert.isTrue(selected.length == 1);
522: ParameterInfo parameterInfo = selected[0];
523: ParameterEditDialog dialog = new ParameterEditDialog(
524: getShell(), parameterInfo, fMode
525: .canChangeTypes(), fMode
526: .canChangeDefault(), fTypeContext);
527: dialog.open();
528: fListener.parameterChanged(parameterInfo);
529: fTableViewer.update(parameterInfo, PROPERTIES);
530: } finally {
531: fTableViewer.getControl().setFocus();
532: }
533: }
534: });
535: return button;
536: }
537:
538: private Button createAddButton(Composite buttonComposite) {
539: Button button = new Button(buttonComposite, SWT.PUSH);
540: button
541: .setText(RefactoringMessages.ChangeParametersControl_buttons_add);
542: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
543: SWTUtil.setButtonDimensionHint(button);
544: button.addSelectionListener(new SelectionAdapter() {
545: public void widgetSelected(SelectionEvent e) {
546: String[] excludedParamNames = new String[fParameterInfos
547: .size()];
548: for (int i = 0; i < fParameterInfos.size(); i++) {
549: ParameterInfo info = (ParameterInfo) fParameterInfos
550: .get(i);
551: excludedParamNames[i] = info.getNewName();
552: }
553: IJavaProject javaProject = fTypeContext.getCuHandle()
554: .getJavaProject();
555: String newParamName = StubUtility
556: .suggestArgumentName(
557: javaProject,
558: RefactoringMessages.ChangeParametersControl_new_parameter_default_name,
559: excludedParamNames);
560: ParameterInfo newInfo = ParameterInfo
561: .createInfoForAddedParameter(
562: "Object", newParamName, "null"); //$NON-NLS-1$ //$NON-NLS-2$
563: int insertIndex = fParameterInfos.size();
564: for (int i = fParameterInfos.size() - 1; i >= 0; i--) {
565: ParameterInfo info = (ParameterInfo) fParameterInfos
566: .get(i);
567: if (info.isNewVarargs()) {
568: insertIndex = i;
569: break;
570: }
571: }
572: fParameterInfos.add(insertIndex, newInfo);
573: fListener.parameterAdded(newInfo);
574: fTableViewer.refresh();
575: fTableViewer.getControl().setFocus();
576: fTableViewer.setSelection(new StructuredSelection(
577: newInfo), true);
578: updateButtonsEnabledState();
579: editColumnOrNextPossible(0);
580: }
581: });
582: return button;
583: }
584:
585: private Button createRemoveButton(Composite buttonComposite) {
586: final Button button = new Button(buttonComposite, SWT.PUSH);
587: button
588: .setText(RefactoringMessages.ChangeParametersControl_buttons_remove);
589: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
590: SWTUtil.setButtonDimensionHint(button);
591: button.addSelectionListener(new SelectionAdapter() {
592: public void widgetSelected(SelectionEvent e) {
593: int index = getTable().getSelectionIndices()[0];
594: ParameterInfo[] selected = getSelectedElements();
595: for (int i = 0; i < selected.length; i++) {
596: if (selected[i].isAdded())
597: fParameterInfos.remove(selected[i]);
598: else
599: selected[i].markAsDeleted();
600: }
601: restoreSelection(index);
602: }
603:
604: private void restoreSelection(int index) {
605: fTableViewer.refresh();
606: fTableViewer.getControl().setFocus();
607: int itemCount = getTableItemCount();
608: if (itemCount != 0 && index >= itemCount) {
609: index = itemCount - 1;
610: getTable().setSelection(index);
611: }
612: fListener.parameterListChanged();
613: updateButtonsEnabledState();
614: }
615: });
616: return button;
617: }
618:
619: private Button createButton(Composite buttonComposite, String text,
620: final boolean up) {
621: Button button = new Button(buttonComposite, SWT.PUSH);
622: button.setText(text);
623: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
624: SWTUtil.setButtonDimensionHint(button);
625: button.addSelectionListener(new SelectionAdapter() {
626: public void widgetSelected(SelectionEvent e) {
627: ISelection savedSelection = fTableViewer.getSelection();
628: if (savedSelection == null)
629: return;
630: ParameterInfo[] selection = getSelectedElements();
631: if (selection.length == 0)
632: return;
633:
634: if (up) {
635: moveUp(selection);
636: } else {
637: moveDown(selection);
638: }
639: fTableViewer.refresh();
640: fTableViewer.setSelection(savedSelection);
641: fListener.parameterListChanged();
642: fTableViewer.getControl().setFocus();
643: }
644: });
645: return button;
646: }
647:
648: //---- editing -----------------------------------------------------------------------------------------------
649:
650: private void addCellEditors() {
651: fTableViewer.setColumnProperties(PROPERTIES);
652:
653: final TableTextCellEditor editors[] = new TableTextCellEditor[PROPERTIES.length];
654:
655: editors[TYPE_PROP] = new TableTextCellEditor(fTableViewer,
656: TYPE_PROP);
657: editors[NEWNAME_PROP] = new TableTextCellEditor(fTableViewer,
658: NEWNAME_PROP);
659: editors[DEFAULT_PROP] = new TableTextCellEditor(fTableViewer,
660: DEFAULT_PROP);
661:
662: if (fMode.canChangeTypes()) {
663: SubjectControlContentAssistant assistant = installParameterTypeContentAssist(editors[TYPE_PROP]
664: .getText());
665: editors[TYPE_PROP].setContentAssistant(assistant);
666: }
667: if (fParamNameProposals.length > 0) {
668: SubjectControlContentAssistant assistant = installParameterNameContentAssist(editors[NEWNAME_PROP]
669: .getText());
670: editors[NEWNAME_PROP].setContentAssistant(assistant);
671: }
672:
673: for (int i = 0; i < editors.length; i++) {
674: final int editorColumn = i;
675: final TableTextCellEditor editor = editors[i];
676: // support tabbing between columns while editing:
677: editor.getText().addTraverseListener(
678: new TraverseListener() {
679: public void keyTraversed(TraverseEvent e) {
680: switch (e.detail) {
681: case SWT.TRAVERSE_TAB_NEXT:
682: editColumnOrNextPossible(nextColumn(editorColumn));
683: e.detail = SWT.TRAVERSE_NONE;
684: break;
685:
686: case SWT.TRAVERSE_TAB_PREVIOUS:
687: editColumnOrPrevPossible(prevColumn(editorColumn));
688: e.detail = SWT.TRAVERSE_NONE;
689: break;
690:
691: default:
692: break;
693: }
694: }
695: });
696: TextFieldNavigationHandler.install(editor.getText());
697: }
698:
699: editors[NEWNAME_PROP]
700: .setActivationListener(new TableTextCellEditor.IActivationListener() {
701: public void activate() {
702: ParameterInfo[] selected = getSelectedElements();
703: if (selected.length == 1
704: && fNameContentAssistHandler != null) {
705: fNameContentAssistHandler
706: .setEnabled(selected[0].isAdded());
707: }
708: }
709: });
710:
711: fTableViewer.setCellEditors(editors);
712: fTableViewer.setCellModifier(new ParametersCellModifier());
713: }
714:
715: private SubjectControlContentAssistant installParameterTypeContentAssist(
716: Text text) {
717: JavaTypeCompletionProcessor processor = new JavaTypeCompletionProcessor(
718: true, false);
719: if (fTypeContext == null)
720: processor.setCompletionContext(null, null, null);
721: else
722: processor.setCompletionContext(fTypeContext.getCuHandle(),
723: fTypeContext.getBeforeString(), fTypeContext
724: .getAfterString());
725: SubjectControlContentAssistant contentAssistant = ControlContentAssistHelper
726: .createJavaContentAssistant(processor);
727: ContentAssistHandler.createHandlerForText(text,
728: contentAssistant);
729: return contentAssistant;
730: }
731:
732: private SubjectControlContentAssistant installParameterNameContentAssist(
733: Text text) {
734: VariableNamesProcessor processor = new VariableNamesProcessor(
735: fParamNameProposals);
736: SubjectControlContentAssistant contentAssistant = ControlContentAssistHelper
737: .createJavaContentAssistant(processor);
738: fNameContentAssistHandler = ContentAssistHandler
739: .createHandlerForText(text, contentAssistant);
740: return contentAssistant;
741: }
742:
743: //---- change order ----------------------------------------------------------------------------------------
744:
745: private void moveUp(ParameterInfo[] selection) {
746: moveUp(fParameterInfos, Arrays.asList(selection));
747: }
748:
749: private void moveDown(ParameterInfo[] selection) {
750: Collections.reverse(fParameterInfos);
751: moveUp(fParameterInfos, Arrays.asList(selection));
752: Collections.reverse(fParameterInfos);
753: }
754:
755: private static void moveUp(List elements, List move) {
756: List res = new ArrayList(elements.size());
757: List deleted = new ArrayList();
758: Object floating = null;
759: for (Iterator iter = elements.iterator(); iter.hasNext();) {
760: Object curr = iter.next();
761: if (move.contains(curr)) {
762: res.add(curr);
763: } else if (((ParameterInfo) curr).isDeleted()) {
764: deleted.add(curr);
765: } else {
766: if (floating != null)
767: res.add(floating);
768: floating = curr;
769: }
770: }
771: if (floating != null) {
772: res.add(floating);
773: }
774: res.addAll(deleted);
775: elements.clear();
776: for (Iterator iter = res.iterator(); iter.hasNext();) {
777: elements.add(iter.next());
778: }
779: }
780:
781: private boolean canMove(boolean up) {
782: int notDeletedInfosCount = getNotDeletedInfosCount();
783: if (notDeletedInfosCount == 0)
784: return false;
785: int[] indc = getTable().getSelectionIndices();
786: if (indc.length == 0)
787: return false;
788: int invalid = up ? 0 : notDeletedInfosCount - 1;
789: for (int i = 0; i < indc.length; i++) {
790: if (indc[i] == invalid)
791: return false;
792: }
793: return true;
794: }
795:
796: private int getNotDeletedInfosCount() {
797: if (fParameterInfos == null) // during initialization
798: return 0;
799: int result = 0;
800: for (Iterator iter = fParameterInfos.iterator(); iter.hasNext();) {
801: ParameterInfo info = (ParameterInfo) iter.next();
802: if (!info.isDeleted())
803: result++;
804: }
805: return result;
806: }
807: }
|