1 /******************************************************************************* 2 * Copyright (c) 2009, 2016 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 *******************************************************************************/ 12 13 package org.eclipse.jdt.internal.ui.callhierarchy; 14 15 import java.util.Arrays; 16 import java.util.List; 17 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.events.SelectionAdapter; 20 import org.eclipse.swt.events.SelectionEvent; 21 import org.eclipse.swt.graphics.Image; 22 import org.eclipse.swt.layout.GridData; 23 import org.eclipse.swt.layout.GridLayout; 24 import org.eclipse.swt.widgets.Button; 25 import org.eclipse.swt.widgets.Composite; 26 import org.eclipse.swt.widgets.Control; 27 import org.eclipse.swt.widgets.Shell; 28 import org.eclipse.swt.widgets.Text; 29 30 import org.eclipse.core.runtime.Assert; 31 import org.eclipse.core.runtime.IStatus; 32 33 import org.eclipse.jface.dialogs.Dialog; 34 import org.eclipse.jface.dialogs.StatusDialog; 35 import org.eclipse.jface.layout.PixelConverter; 36 import org.eclipse.jface.operation.IRunnableContext; 37 import org.eclipse.jface.viewers.LabelProvider; 38 import org.eclipse.jface.viewers.ViewerComparator; 39 import org.eclipse.jface.window.Window; 40 41 import org.eclipse.ui.PlatformUI; 42 import org.eclipse.ui.dialogs.SelectionDialog; 43 import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; 44 45 import org.eclipse.jdt.core.IType; 46 import org.eclipse.jdt.core.JavaConventions; 47 import org.eclipse.jdt.core.JavaCore; 48 import org.eclipse.jdt.core.JavaModelException; 49 import org.eclipse.jdt.core.search.IJavaSearchScope; 50 import org.eclipse.jdt.core.search.SearchEngine; 51 52 import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; 53 54 import org.eclipse.jdt.ui.IJavaElementSearchConstants; 55 import org.eclipse.jdt.ui.JavaUI; 56 import org.eclipse.jdt.ui.PreferenceConstants; 57 58 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; 59 import org.eclipse.jdt.internal.ui.JavaPluginImages; 60 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; 61 import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler; 62 import org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock; 63 import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext; 64 import org.eclipse.jdt.internal.ui.util.ExceptionHandler; 65 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; 66 import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener; 67 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; 68 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; 69 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter; 70 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter; 71 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil; 72 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField; 73 import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField; 74 75 /** 76 * Call hierarchy expand with constructors configuration block. 77 * 78 * @since 3.6 79 */ 80 public class ExpandWithConstructorsConfigurationBlock extends OptionsConfigurationBlock { 81 82 /** 83 * Call hierarchy expand with constructors dialog for types and members. 84 */ 85 private static class CallHierarchyTypesOrMembersDialog extends StatusDialog { 86 87 /** 88 * The change listener class for the dialog field and the string button dialog field. 89 * 90 */ 91 private class StringButtonAdapter implements IDialogFieldListener, IStringButtonAdapter { 92 /* 93 * @see IDialogFieldListener#dialogFieldChanged(DialogField) 94 */ 95 @Override dialogFieldChanged(DialogField field)96 public void dialogFieldChanged(DialogField field) { 97 doValidation(); 98 } 99 100 /* 101 * @see IStringButtonAdapter#changeControlPressed(DialogField) 102 */ 103 @Override changeControlPressed(DialogField field)104 public void changeControlPressed(DialogField field) { 105 doBrowseTypes(); 106 } 107 } 108 109 /** 110 * The name dialog field to hold the default expand with constructors list. 111 */ 112 private StringButtonDialogField fNameDialogField; 113 114 /** 115 * The list of previously existing entries. 116 */ 117 private List<String> fExistingEntries; 118 119 /** 120 * Tells whether it is an member or type. 121 */ 122 private final boolean fIsEditingMember; 123 124 /** 125 * Creates a call hierarchy preference dialog for members or types. 126 * 127 * @param parent the parent shell 128 * @param existingEntries the existing list of types and members 129 * @param isEditingMember <code>true</code if its a member, <code>false</code> otherwise 130 */ CallHierarchyTypesOrMembersDialog(Shell parent, List<String> existingEntries, boolean isEditingMember)131 public CallHierarchyTypesOrMembersDialog(Shell parent, List<String> existingEntries, boolean isEditingMember) { 132 super(parent); 133 fIsEditingMember= isEditingMember; 134 fExistingEntries= existingEntries; 135 136 String label, title; 137 if (isEditingMember) { 138 title= CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_member_title; 139 label= CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_member_labelText; 140 } else { 141 title= CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_type_title; 142 label= CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_type_labelText; 143 } 144 setTitle(title); 145 146 StringButtonAdapter adapter= new StringButtonAdapter(); 147 148 fNameDialogField= new StringButtonDialogField(adapter); 149 fNameDialogField.setLabelText(label); 150 fNameDialogField.setButtonLabel(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_browse_button); 151 fNameDialogField.setDialogFieldListener(adapter); 152 fNameDialogField.setText(""); //$NON-NLS-1$ 153 } 154 155 /* 156 * @see org.eclipse.jface.dialogs.Dialog#isResizable() * 157 */ 158 @Override isResizable()159 protected boolean isResizable() { 160 return true; 161 } 162 163 /** 164 * Sets the initial selection in the name dialog field. 165 * 166 * @param editedEntry the edited entry 167 */ setInitialSelection(String editedEntry)168 public void setInitialSelection(String editedEntry) { 169 Assert.isNotNull(editedEntry); 170 if (editedEntry.length() == 0) 171 fNameDialogField.setText(""); //$NON-NLS-1$ 172 else 173 fNameDialogField.setText(editedEntry); 174 } 175 176 /** 177 * Returns the resulting text from the name dialog field. 178 * 179 * @return the resulting text from the name dialog field 180 */ getResult()181 public String getResult() { 182 String val= fNameDialogField.getText(); 183 if (!fIsEditingMember) 184 val= val + WILDCARD; 185 return val; 186 } 187 188 /* 189 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) 190 */ 191 @Override createDialogArea(Composite parent)192 protected Control createDialogArea(Composite parent) { 193 Composite composite= (Composite)super.createDialogArea(parent); 194 initializeDialogUnits(composite); 195 196 GridLayout layout= (GridLayout)composite.getLayout(); 197 layout.numColumns= 2; 198 199 fNameDialogField.doFillIntoGrid(composite, 3); 200 201 fNameDialogField.getChangeControl(null).setVisible(!fIsEditingMember); 202 203 LayoutUtil.setHorizontalSpan(fNameDialogField.getLabelControl(null), 2); 204 205 int fieldWidthHint= convertWidthInCharsToPixels(60); 206 Text text= fNameDialogField.getTextControl(null); 207 LayoutUtil.setWidthHint(text, fieldWidthHint); 208 LayoutUtil.setHorizontalGrabbing(text); 209 LayoutUtil.setHorizontalSpan(text, fIsEditingMember ? 2 : 1); 210 TextFieldNavigationHandler.install(text); 211 212 DialogField.createEmptySpace(composite, 1); 213 214 fNameDialogField.postSetFocusOnDialogField(parent.getDisplay()); 215 216 applyDialogFont(composite); 217 return composite; 218 } 219 220 /** 221 * Creates the type hierarchy for type selection. 222 */ doBrowseTypes()223 private void doBrowseTypes() { 224 IRunnableContext context= new BusyIndicatorRunnableContext(); 225 IJavaSearchScope scope= SearchEngine.createWorkspaceScope(); 226 int style= IJavaElementSearchConstants.CONSIDER_ALL_TYPES; 227 try { 228 SelectionDialog dialog= JavaUI.createTypeDialog(getShell(), context, scope, style, false, fNameDialogField.getText()); 229 dialog.setTitle(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_ChooseTypeDialog_title); 230 dialog.setMessage(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_ChooseTypeDialog_description); 231 if (dialog.open() == Window.OK) { 232 IType res= (IType)dialog.getResult()[0]; 233 fNameDialogField.setText(res.getFullyQualifiedName('.')); 234 } 235 } catch (JavaModelException e) { 236 ExceptionHandler.handle(e, getShell(), CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_ChooseTypeDialog_title, 237 CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_ChooseTypeDialog_error_message); 238 } 239 } 240 241 /** 242 * Validates the entered type or member and updates the status. 243 */ doValidation()244 private void doValidation() { 245 StatusInfo status= new StatusInfo(); 246 String newText= fNameDialogField.getText(); 247 if (newText.length() == 0) { 248 status.setError(""); //$NON-NLS-1$ 249 } else { 250 IStatus val= JavaConventions.validateJavaTypeName(newText, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3, null); 251 if (val.matches(IStatus.ERROR)) { 252 if (fIsEditingMember) 253 status.setError(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_error_invalidMemberName); 254 else 255 status.setError(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_error_invalidTypeName); 256 } else { 257 if (doesExist(newText)) { 258 status.setError(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_error_entryExists); 259 } 260 } 261 } 262 updateStatus(status); 263 } 264 265 /** 266 * Checks if the entry already exists. 267 * 268 * @param name the type or member name 269 * @return <code>true</code> if it already exists in the list of types and members, 270 * <code>false</code> otherwise 271 */ doesExist(String name)272 private boolean doesExist(String name) { 273 return fExistingEntries.contains(name); 274 } 275 276 277 /* 278 * @see org.eclipse.jface.window.Window#configureShell(Shell) 279 */ 280 @Override configureShell(Shell newShell)281 protected void configureShell(Shell newShell) { 282 super.configureShell(newShell); 283 PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IJavaHelpContextIds.CALL_HIERARCHY_EXPAND_WITH_CONSTRUCTORS_DIALOG); 284 } 285 286 } 287 288 /* 289 * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#performOk() 290 */ 291 @Override performOk()292 public boolean performOk() { 293 setValue(ANONYMOUS_EXPAND_WITH_CONSTRUCTORS, fIsAnonymous); 294 return super.performOk(); 295 } 296 297 /** 298 * The list label provider class. 299 */ 300 private static class ListLabelProvider extends LabelProvider { 301 302 public final Image MEMBER_ICON; 303 304 private final Image CLASS_ICON; 305 306 /** 307 * Create the member and class icons. 308 */ ListLabelProvider()309 public ListLabelProvider() { 310 MEMBER_ICON= JavaElementImageProvider.getDecoratedImage(JavaPluginImages.DESC_MISC_PUBLIC, 0, JavaElementImageProvider.SMALL_SIZE); 311 CLASS_ICON= JavaElementImageProvider.getDecoratedImage(JavaPluginImages.DESC_OBJS_CLASS, 0, JavaElementImageProvider.SMALL_SIZE); 312 } 313 314 /* 315 * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) 316 */ 317 @Override getImage(Object element)318 public Image getImage(Object element) { 319 return ((String)element).endsWith(WILDCARD) ? CLASS_ICON : MEMBER_ICON; 320 } 321 322 /* 323 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) 324 */ 325 @Override getText(Object element)326 public String getText(Object element) { 327 return BasicElementLabels.getJavaElementName((String)element); 328 } 329 } 330 331 332 /** 333 * The change listener for <code>ListDialogField</code>. 334 */ 335 private class ListAdapter implements IListAdapter<String>, IDialogFieldListener { 336 337 /** 338 * Checks if field can be edited. 339 * 340 * @param field the list dialog field 341 * @return <code>true</code> if it can be edited, <code>false</code> otherwise 342 */ canEdit(ListDialogField<String> field)343 private boolean canEdit(ListDialogField<String> field) { 344 List<String> selected= field.getSelectedElements(); 345 return selected.size() == 1; 346 } 347 348 /* 349 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#customButtonPressed(org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField, int) 350 */ 351 @Override customButtonPressed(ListDialogField<String> field, int index)352 public void customButtonPressed(ListDialogField<String> field, int index) { 353 doButtonPressed(index); 354 } 355 356 /* 357 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#selectionChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField) 358 */ 359 @Override selectionChanged(ListDialogField<String> field)360 public void selectionChanged(ListDialogField<String> field) { 361 fList.enableButton(IDX_EDIT, canEdit(field)); 362 fList.enableButton(IDX_REMOVE, canRemove(field)); 363 } 364 365 /** 366 * Checks if the field can be removed. 367 * 368 * @param field the list dialog field 369 * @return <code>true</code> if it can be removed, <code>false</code> otherwise 370 */ canRemove(ListDialogField<String> field)371 private boolean canRemove(ListDialogField<String> field) { 372 List<String> selected= field.getSelectedElements(); 373 return !selected.isEmpty(); 374 } 375 376 /* ) 377 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField) 378 */ 379 @Override dialogFieldChanged(DialogField field)380 public void dialogFieldChanged(DialogField field) { 381 doDialogFieldChanged(field); 382 } 383 384 /* 385 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#doubleClicked(org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField) 386 */ 387 @Override doubleClicked(ListDialogField<String> field)388 public void doubleClicked(ListDialogField<String> field) { 389 if (canEdit(field)) { 390 doButtonPressed(IDX_EDIT); 391 } 392 } 393 } 394 395 private static final String WILDCARD= ".*"; //$NON-NLS-1$ 396 397 private static final int IDX_NEW_TYPE= 0; 398 private static final int IDX_NEW_MEMBER= 1; 399 private static final int IDX_EDIT= 2; 400 private static final int IDX_REMOVE= 3; 401 private static final int IDX_RESTORE_DEFAULTS= 4; 402 403 private ListDialogField<String> fList; 404 405 private Button fAnonymousButton; 406 407 protected boolean fIsAnonymous; 408 409 /** 410 * A key that holds the list of methods or types whose methods are by default expanded with constructors in the Call Hierarchy. 411 */ 412 private static Key DEFAULT_EXPAND_WITH_CONSTRUCTORS_MEMBERS= getJDTUIKey(PreferenceConstants.PREF_DEFAULT_EXPAND_WITH_CONSTRUCTORS_MEMBERS); 413 414 /** 415 * A key that controls whether the methods from anonymous types are by default expanded with constructors in the Call Hierarchy. 416 */ 417 private static Key ANONYMOUS_EXPAND_WITH_CONSTRUCTORS= getJDTUIKey(PreferenceConstants.PREF_ANONYMOUS_EXPAND_WITH_CONSTRUCTORS); 418 419 /** 420 * Returns all the key values. 421 * 422 * @return array of keys 423 */ getAllKeys()424 public static Key[] getAllKeys() { 425 return new Key[] { DEFAULT_EXPAND_WITH_CONSTRUCTORS_MEMBERS, ANONYMOUS_EXPAND_WITH_CONSTRUCTORS }; 426 } 427 428 429 /** 430 * Creates the call hierarchy preferences configuration block. 431 * 432 * @param context the status 433 * @param container the preference container 434 */ ExpandWithConstructorsConfigurationBlock(IStatusChangeListener context, IWorkbenchPreferenceContainer container)435 public ExpandWithConstructorsConfigurationBlock(IStatusChangeListener context, IWorkbenchPreferenceContainer container) { 436 super(context, null, getAllKeys(), container); 437 } 438 439 /* 440 * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite) 441 */ 442 @Override createContents(Composite parent)443 protected Control createContents(Composite parent) { 444 Composite control= new Composite(parent, SWT.NONE); 445 GridLayout layout= new GridLayout(); 446 layout.numColumns= 2; 447 layout.marginWidth= 10; 448 layout.marginHeight= 10; 449 control.setLayout(layout); 450 451 createPreferenceList(control); 452 453 fAnonymousButton= new Button(control, SWT.CHECK); 454 fAnonymousButton.setText(CallHierarchyMessages.CallHierarchyTypesOrMembersDialog_anonymousTypes_label); 455 fIsAnonymous= getBooleanValue(ANONYMOUS_EXPAND_WITH_CONSTRUCTORS); 456 fAnonymousButton.setSelection(fIsAnonymous); 457 fAnonymousButton.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false)); 458 fAnonymousButton.addSelectionListener(new SelectionAdapter() { 459 @Override 460 public void widgetSelected(SelectionEvent e) { 461 fIsAnonymous= fAnonymousButton.getSelection(); 462 } 463 464 }); 465 466 initialize(); 467 468 Dialog.applyDialogFont(control); 469 470 return control; 471 } 472 473 /** 474 * Create a list dialog field. 475 * 476 * @param parent the composite 477 */ createPreferenceList(Composite parent)478 private void createPreferenceList(Composite parent) { 479 String[] buttonLabels= new String[] { 480 CallHierarchyMessages.ExpandWithConstructorsConfigurationBlock_newType_button, 481 CallHierarchyMessages.ExpandWithConstructorsConfigurationBlock_newMember_button, 482 CallHierarchyMessages.ExpandWithConstructorsConfigurationBlock_edit_button, 483 CallHierarchyMessages.ExpandWithConstructorsConfigurationBlock_remove_button, 484 CallHierarchyMessages.ExpandWithConstructorsConfigurationBlock_restoreDefaults_button 485 }; 486 487 ListAdapter adapter= new ListAdapter(); 488 489 fList= new ListDialogField<>(adapter, buttonLabels, new ListLabelProvider()); 490 fList.setDialogFieldListener(adapter); 491 fList.setLabelText(CallHierarchyMessages.ExpandWithConstructorsConfigurationBlock_description); 492 fList.setRemoveButtonIndex(IDX_REMOVE); 493 fList.enableButton(IDX_EDIT, false); 494 fList.setViewerComparator(new ViewerComparator()); 495 496 PixelConverter pixelConverter= new PixelConverter(parent); 497 498 fList.doFillIntoGrid(parent, 3); 499 LayoutUtil.setHorizontalSpan(fList.getLabelControl(null), 2); 500 LayoutUtil.setWidthHint(fList.getLabelControl(null), pixelConverter.convertWidthInCharsToPixels(60)); 501 LayoutUtil.setHorizontalGrabbing(fList.getListControl(null)); 502 503 Control listControl= fList.getListControl(null); 504 GridData gd= (GridData)listControl.getLayoutData(); 505 gd.verticalAlignment= GridData.FILL; 506 gd.grabExcessVerticalSpace= true; 507 gd.heightHint= pixelConverter.convertHeightInCharsToPixels(10); 508 } 509 510 /** 511 * Initialize the elements of the list dialog field. 512 */ initialize()513 public void initialize() { 514 fList.setElements(Arrays.asList(getDefaultExpandWithConstructorsMembers())); 515 } 516 517 /* 518 * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#performDefaults() 519 */ 520 @Override performDefaults()521 public void performDefaults() { 522 String str= PreferenceConstants.getPreferenceStore().getDefaultString(PreferenceConstants.PREF_DEFAULT_EXPAND_WITH_CONSTRUCTORS_MEMBERS); 523 fList.setElements(Arrays.asList(deserializeMembers(str))); 524 fIsAnonymous= PreferenceConstants.getPreferenceStore().getDefaultBoolean(PreferenceConstants.PREF_ANONYMOUS_EXPAND_WITH_CONSTRUCTORS); 525 fAnonymousButton.setSelection(fIsAnonymous); 526 super.performDefaults(); 527 } 528 529 /* 530 * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean) 531 */ 532 @Override getFullBuildDialogStrings(boolean workspaceSettings)533 protected String[] getFullBuildDialogStrings(boolean workspaceSettings) { 534 return null; 535 } 536 537 /* 538 * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key, java.lang.String, java.lang.String) 539 */ 540 @Override validateSettings(Key changedKey, String oldValue, String newValue)541 protected void validateSettings(Key changedKey, String oldValue, String newValue) { 542 543 } 544 545 /** 546 * Perform the 'New' and 'Edit' button operations by opening the respective call hierarchy 547 * preferences dialog, and 'Restore Defaults' button by restoring to default values for the list dialog. 548 * 549 * @param index the index of the button 550 */ doButtonPressed(int index)551 private void doButtonPressed(int index) { 552 switch (index) { 553 case IDX_NEW_TYPE: 554 case IDX_NEW_MEMBER: 555 { 556 // add new 557 List<String> existing= fList.getElements(); 558 CallHierarchyTypesOrMembersDialog dialog= new CallHierarchyTypesOrMembersDialog(getShell(), existing, index == IDX_NEW_MEMBER); 559 if (dialog.open() == Window.OK) { 560 fList.addElement(dialog.getResult()); 561 } break; 562 } 563 case IDX_EDIT: 564 { 565 // edit 566 List<String> selected= fList.getSelectedElements(); 567 if (selected.isEmpty()) 568 return; 569 String editedEntry= selected.get(0); 570 List<String> existing= fList.getElements(); 571 existing.remove(editedEntry); 572 boolean isType= editedEntry.endsWith(WILDCARD); 573 CallHierarchyTypesOrMembersDialog dialog= new CallHierarchyTypesOrMembersDialog(getShell(), existing, !isType); 574 if (isType) 575 dialog.setInitialSelection(editedEntry.substring(0, editedEntry.length() - 2)); 576 else 577 dialog.setInitialSelection(editedEntry); 578 if (dialog.open() == Window.OK) { 579 fList.replaceElement(editedEntry, dialog.getResult()); 580 } break; 581 } 582 case IDX_RESTORE_DEFAULTS: 583 performDefaults(); 584 break; 585 default: 586 break; 587 } 588 } 589 590 /** 591 * Update the key on dialog field change. 592 * 593 * @param field the dialog field 594 */ doDialogFieldChanged(DialogField field)595 protected final void doDialogFieldChanged(DialogField field) { 596 // set values in working copy 597 if (field == fList) { 598 setValue(DEFAULT_EXPAND_WITH_CONSTRUCTORS_MEMBERS, serializeMembers(fList.getElements())); 599 } 600 } 601 602 /** 603 * Returns the array of strings containing the types or methods for default expand with constructors. 604 * 605 * @return the array of strings containing the types or methods for default expand with constructors 606 */ getDefaultExpandWithConstructorsMembers()607 private String[] getDefaultExpandWithConstructorsMembers() { 608 String str= getValue(DEFAULT_EXPAND_WITH_CONSTRUCTORS_MEMBERS); 609 if (str != null && str.length() > 0) { 610 return deserializeMembers(str); 611 } 612 return new String[0]; 613 } 614 615 /** 616 * Return the array of types and/or methods after splitting the stored preference string. 617 * 618 * @param str the input string 619 * @return the array of types and/or methods 620 */ deserializeMembers(String str)621 private static String[] deserializeMembers(String str) { 622 return str.split(";"); //$NON-NLS-1$ 623 } 624 625 /** 626 * Creates a single output string from the list of strings using a delimiter. 627 * 628 * @param list the input list of types and/or methods 629 * @return the single output string from the list of strings using a delimiter 630 */ serializeMembers(List<String> list)631 public static String serializeMembers(List<String> list) { 632 return String.join(";", list.toArray(new String[list.size()])); //$NON-NLS-1$ 633 } 634 635 } 636