1 11 package org.eclipse.jdt.internal.ui.wizards.buildpaths; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.CoreException; 18 import org.eclipse.core.runtime.IPath; 19 import org.eclipse.core.runtime.Path; 20 21 import org.eclipse.core.resources.IContainer; 22 import org.eclipse.core.resources.IProject; 23 import org.eclipse.core.resources.IResource; 24 25 import org.eclipse.swt.SWT; 26 import org.eclipse.swt.events.KeyEvent; 27 import org.eclipse.swt.widgets.Composite; 28 import org.eclipse.swt.widgets.Control; 29 import org.eclipse.swt.widgets.Display; 30 import org.eclipse.swt.widgets.Shell; 31 32 import org.eclipse.jface.action.IAction; 33 import org.eclipse.jface.util.IPropertyChangeListener; 34 import org.eclipse.jface.util.PropertyChangeEvent; 35 import org.eclipse.jface.viewers.StructuredSelection; 36 import org.eclipse.jface.window.Window; 37 38 import org.eclipse.ui.INewWizard; 39 40 import org.eclipse.jdt.core.IClasspathEntry; 41 import org.eclipse.jdt.core.IJavaProject; 42 43 import org.eclipse.jdt.internal.corext.buildpath.ClasspathModifier; 44 45 import org.eclipse.jdt.ui.actions.AbstractOpenWizardAction; 46 47 import org.eclipse.jdt.internal.ui.JavaPlugin; 48 import org.eclipse.jdt.internal.ui.util.PixelConverter; 49 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; 50 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; 51 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; 52 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ITreeListAdapter; 53 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil; 54 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField; 55 import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField; 56 import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField; 57 import org.eclipse.jdt.internal.ui.wizards.dialogfields.TreeListDialogField; 58 59 public class SourceContainerWorkbookPage extends BuildPathBasePage { 60 61 private class OpenBuildPathWizardAction extends AbstractOpenWizardAction implements IPropertyChangeListener { 62 63 private final BuildPathWizard fWizard; 64 private final List fSelectedElements; 65 66 public OpenBuildPathWizardAction(BuildPathWizard wizard) { 67 fWizard= wizard; 68 addPropertyChangeListener(this); 69 fSelectedElements= fFoldersList.getSelectedElements(); 70 } 71 72 75 protected INewWizard createWizard() throws CoreException { 76 return fWizard; 77 } 78 79 82 public void propertyChange(PropertyChangeEvent event) { 83 if (event.getProperty().equals(IAction.RESULT)) { 84 if (event.getNewValue().equals(Boolean.TRUE)) { 85 finishWizard(); 86 } else { 87 fWizard.cancel(); 88 } 89 } 90 } 91 92 protected void finishWizard() { 93 List insertedElements= fWizard.getInsertedElements(); 94 refresh(insertedElements, fWizard.getRemovedElements(), fWizard.getModifiedElements(), fWizard.getOutputLocation()); 95 96 if (insertedElements.isEmpty()) { 97 fFoldersList.postSetSelection(new StructuredSelection(fSelectedElements)); 98 } 99 } 100 101 } 102 103 private static AddSourceFolderWizard newSourceFolderWizard(CPListElement element, List existingElements, String outputLocation, boolean newFolder) { 104 CPListElement[] existing= (CPListElement[])existingElements.toArray(new CPListElement[existingElements.size()]); 105 AddSourceFolderWizard wizard= new AddSourceFolderWizard(existing, element, new Path(outputLocation).makeAbsolute(), false, newFolder, newFolder, newFolder?CPListElement.isProjectSourceFolder(existing, element.getJavaProject()):false, newFolder); 106 wizard.setDoFlushChange(false); 107 return wizard; 108 } 109 110 private static AddSourceFolderWizard newLinkedSourceFolderWizard(CPListElement element, List existingElements, String outputLocation, boolean newFolder) { 111 CPListElement[] existing= (CPListElement[])existingElements.toArray(new CPListElement[existingElements.size()]); 112 AddSourceFolderWizard wizard= new AddSourceFolderWizard(existing, element, new Path(outputLocation).makeAbsolute(), true, newFolder, newFolder, newFolder?CPListElement.isProjectSourceFolder(existing, element.getJavaProject()):false, newFolder); 113 wizard.setDoFlushChange(false); 114 return wizard; 115 } 116 117 private static EditFilterWizard newEditFilterWizard(CPListElement element, List existingElements, String outputLocation) { 118 CPListElement[] existing= (CPListElement[])existingElements.toArray(new CPListElement[existingElements.size()]); 119 EditFilterWizard result = new EditFilterWizard(existing, element, new Path(outputLocation).makeAbsolute()); 120 result.setDoFlushChange(false); 121 return result; 122 } 123 124 private ListDialogField fClassPathList; 125 private IJavaProject fCurrJProject; 126 127 private Control fSWTControl; 128 private TreeListDialogField fFoldersList; 129 130 private StringDialogField fOutputLocationField; 131 132 private SelectionButtonDialogField fUseFolderOutputs; 133 134 private final int IDX_ADD= 0; 135 private final int IDX_ADD_LINK= 1; 136 private final int IDX_EDIT= 3; 137 private final int IDX_REMOVE= 4; 138 139 public SourceContainerWorkbookPage(ListDialogField classPathList, StringDialogField outputLocationField) { 140 fClassPathList= classPathList; 141 142 fOutputLocationField= outputLocationField; 143 144 fSWTControl= null; 145 146 SourceContainerAdapter adapter= new SourceContainerAdapter(); 147 148 String [] buttonLabels; 149 150 buttonLabels= new String [] { 151 NewWizardMessages.SourceContainerWorkbookPage_folders_add_button, 152 NewWizardMessages.SourceContainerWorkbookPage_folders_link_source_button, 153 null, 154 NewWizardMessages.SourceContainerWorkbookPage_folders_edit_button, 155 NewWizardMessages.SourceContainerWorkbookPage_folders_remove_button 156 }; 157 158 fFoldersList= new TreeListDialogField(adapter, buttonLabels, new CPListLabelProvider()); 159 fFoldersList.setDialogFieldListener(adapter); 160 fFoldersList.setLabelText(NewWizardMessages.SourceContainerWorkbookPage_folders_label); 161 162 fFoldersList.setViewerComparator(new CPListElementSorter()); 163 fFoldersList.enableButton(IDX_EDIT, false); 164 165 fUseFolderOutputs= new SelectionButtonDialogField(SWT.CHECK); 166 fUseFolderOutputs.setSelection(false); 167 fUseFolderOutputs.setLabelText(NewWizardMessages.SourceContainerWorkbookPage_folders_check); 168 fUseFolderOutputs.setDialogFieldListener(adapter); 169 } 170 171 public void init(IJavaProject jproject) { 172 fCurrJProject= jproject; 173 if (Display.getCurrent() != null) { 174 updateFoldersList(); 175 } else { 176 Display.getDefault().asyncExec(new Runnable () { 177 public void run() { 178 updateFoldersList(); 179 } 180 }); 181 } 182 } 183 184 private void updateFoldersList() { 185 if (fSWTControl == null || fSWTControl.isDisposed()) { 186 return; 187 } 188 189 ArrayList folders= new ArrayList (); 190 191 boolean useFolderOutputs= false; 192 List cpelements= fClassPathList.getElements(); 193 for (int i= 0; i < cpelements.size(); i++) { 194 CPListElement cpe= (CPListElement)cpelements.get(i); 195 if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE) { 196 folders.add(cpe); 197 boolean hasOutputFolder= (cpe.getAttribute(CPListElement.OUTPUT) != null); 198 if (hasOutputFolder) { 199 useFolderOutputs= true; 200 } 201 202 } 203 } 204 fFoldersList.setElements(folders); 205 fUseFolderOutputs.setSelection(useFolderOutputs); 206 207 for (int i= 0; i < folders.size(); i++) { 208 CPListElement cpe= (CPListElement) folders.get(i); 209 IPath[] ePatterns= (IPath[]) cpe.getAttribute(CPListElement.EXCLUSION); 210 IPath[] iPatterns= (IPath[])cpe.getAttribute(CPListElement.INCLUSION); 211 boolean hasOutputFolder= (cpe.getAttribute(CPListElement.OUTPUT) != null); 212 if (ePatterns.length > 0 || iPatterns.length > 0 || hasOutputFolder) { 213 fFoldersList.expandElement(cpe, 3); 214 } 215 } 216 } 217 218 public Control getControl(Composite parent) { 219 PixelConverter converter= new PixelConverter(parent); 220 Composite composite= new Composite(parent, SWT.NONE); 221 222 LayoutUtil.doDefaultLayout(composite, new DialogField[] { fFoldersList, fUseFolderOutputs , fOutputLocationField}, true, SWT.DEFAULT, SWT.DEFAULT); 223 LayoutUtil.setHorizontalGrabbing(fFoldersList.getTreeControl(null)); 224 225 int buttonBarWidth= converter.convertWidthInCharsToPixels(24); 226 fFoldersList.setButtonsMinWidth(buttonBarWidth); 227 228 fSWTControl= composite; 229 230 List elements= fFoldersList.getElements(); 232 for (int i= 0; i < elements.size(); i++) { 233 CPListElement elem= (CPListElement) elements.get(i); 234 IPath[] exclusionPatterns= (IPath[]) elem.getAttribute(CPListElement.EXCLUSION); 235 IPath[] inclusionPatterns= (IPath[]) elem.getAttribute(CPListElement.INCLUSION); 236 IPath output= (IPath) elem.getAttribute(CPListElement.OUTPUT); 237 if (exclusionPatterns.length > 0 || inclusionPatterns.length > 0 || output != null) { 238 fFoldersList.expandElement(elem, 3); 239 } 240 } 241 return composite; 242 } 243 244 private Shell getShell() { 245 if (fSWTControl != null) { 246 return fSWTControl.getShell(); 247 } 248 return JavaPlugin.getActiveWorkbenchShell(); 249 } 250 251 252 private class SourceContainerAdapter implements ITreeListAdapter, IDialogFieldListener { 253 254 private final Object [] EMPTY_ARR= new Object [0]; 255 256 public void customButtonPressed(TreeListDialogField field, int index) { 258 sourcePageCustomButtonPressed(field, index); 259 } 260 261 public void selectionChanged(TreeListDialogField field) { 262 sourcePageSelectionChanged(field); 263 } 264 265 public void doubleClicked(TreeListDialogField field) { 266 sourcePageDoubleClicked(field); 267 } 268 269 public void keyPressed(TreeListDialogField field, KeyEvent event) { 270 sourcePageKeyPressed(field, event); 271 } 272 273 public Object [] getChildren(TreeListDialogField field, Object element) { 274 if (element instanceof CPListElement) { 275 return ((CPListElement) element).getChildren(!fUseFolderOutputs.isSelected()); 276 } 277 return EMPTY_ARR; 278 } 279 280 public Object getParent(TreeListDialogField field, Object element) { 281 if (element instanceof CPListElementAttribute) { 282 return ((CPListElementAttribute) element).getParent(); 283 } 284 return null; 285 } 286 287 public boolean hasChildren(TreeListDialogField field, Object element) { 288 return (element instanceof CPListElement); 289 } 290 291 public void dialogFieldChanged(DialogField field) { 293 sourcePageDialogFieldChanged(field); 294 } 295 296 } 297 298 protected void sourcePageKeyPressed(TreeListDialogField field, KeyEvent event) { 299 if (field == fFoldersList) { 300 if (event.character == SWT.DEL && event.stateMask == 0) { 301 List selection= field.getSelectedElements(); 302 if (canRemove(selection)) { 303 removeEntry(); 304 } 305 } 306 } 307 } 308 309 protected void sourcePageDoubleClicked(TreeListDialogField field) { 310 if (field == fFoldersList) { 311 List selection= field.getSelectedElements(); 312 if (canEdit(selection)) { 313 editEntry(); 314 } 315 } 316 } 317 318 protected void sourcePageCustomButtonPressed(DialogField field, int index) { 319 if (field == fFoldersList) { 320 if (index == IDX_ADD) { 321 IProject project= fCurrJProject.getProject(); 322 if (project.exists() && hasFolders(project)) { 323 List existingElements= fFoldersList.getElements(); 324 CPListElement[] existing= (CPListElement[])existingElements.toArray(new CPListElement[existingElements.size()]); 325 CreateMultipleSourceFoldersDialog dialog= new CreateMultipleSourceFoldersDialog(fCurrJProject, existing, fOutputLocationField.getText(), getShell()); 326 if (dialog.open() == Window.OK) { 327 refresh(dialog.getInsertedElements(), dialog.getRemovedElements(), dialog.getModifiedElements(), dialog.getOutputLocation()); 328 } 329 } else { 330 CPListElement newElement= new CPListElement(fCurrJProject, IClasspathEntry.CPE_SOURCE); 331 AddSourceFolderWizard wizard= newSourceFolderWizard(newElement, fFoldersList.getElements(), fOutputLocationField.getText(), true); 332 OpenBuildPathWizardAction action= new OpenBuildPathWizardAction(wizard); 333 action.run(); 334 } 335 } else if (index == IDX_ADD_LINK) { 336 CPListElement newElement= new CPListElement(fCurrJProject, IClasspathEntry.CPE_SOURCE); 337 AddSourceFolderWizard wizard= newLinkedSourceFolderWizard(newElement, fFoldersList.getElements(), fOutputLocationField.getText(), true); 338 OpenBuildPathWizardAction action= new OpenBuildPathWizardAction(wizard); 339 action.run(); 340 } else if (index == IDX_EDIT) { 341 editEntry(); 342 } else if (index == IDX_REMOVE) { 343 removeEntry(); 344 } 345 } 346 } 347 348 private boolean hasFolders(IContainer container) { 349 350 try { 351 IResource[] members= container.members(); 352 for (int i= 0; i < members.length; i++) { 353 if (members[i] instanceof IContainer) { 354 return true; 355 } 356 } 357 } catch (CoreException e) { 358 } 360 361 List elements= fFoldersList.getElements(); 362 if (elements.size() > 1) 363 return true; 364 365 if (elements.size() == 0) 366 return false; 367 368 CPListElement single= (CPListElement)elements.get(0); 369 if (single.getPath().equals(fCurrJProject.getPath())) 370 return false; 371 372 return true; 373 } 374 375 private void editEntry() { 376 List selElements= fFoldersList.getSelectedElements(); 377 if (selElements.size() != 1) { 378 return; 379 } 380 Object elem= selElements.get(0); 381 if (fFoldersList.getIndexOfElement(elem) != -1) { 382 editElementEntry((CPListElement) elem); 383 } else if (elem instanceof CPListElementAttribute) { 384 editAttributeEntry((CPListElementAttribute) elem); 385 } 386 } 387 388 private void editElementEntry(CPListElement elem) { 389 if (elem.getLinkTarget() != null) { 390 AddSourceFolderWizard wizard= newLinkedSourceFolderWizard(elem, fFoldersList.getElements(), fOutputLocationField.getText(), false); 391 OpenBuildPathWizardAction action= new OpenBuildPathWizardAction(wizard); 392 action.run(); 393 } else { 394 AddSourceFolderWizard wizard= newSourceFolderWizard(elem, fFoldersList.getElements(), fOutputLocationField.getText(), false); 395 OpenBuildPathWizardAction action= new OpenBuildPathWizardAction(wizard); 396 action.run(); 397 } 398 } 399 400 private void editAttributeEntry(CPListElementAttribute elem) { 401 String key= elem.getKey(); 402 if (key.equals(CPListElement.OUTPUT)) { 403 CPListElement selElement= elem.getParent(); 404 OutputLocationDialog dialog= new OutputLocationDialog(getShell(), selElement, fClassPathList.getElements(), new Path(fOutputLocationField.getText()).makeAbsolute(), true); 405 if (dialog.open() == Window.OK) { 406 selElement.setAttribute(CPListElement.OUTPUT, dialog.getOutputLocation()); 407 fFoldersList.refresh(); 408 fClassPathList.dialogFieldChanged(); } 410 } else if (key.equals(CPListElement.EXCLUSION) || key.equals(CPListElement.INCLUSION)) { 411 EditFilterWizard wizard= newEditFilterWizard(elem.getParent(), fFoldersList.getElements(), fOutputLocationField.getText()); 412 OpenBuildPathWizardAction action= new OpenBuildPathWizardAction(wizard); 413 action.run(); 414 } else { 415 if (editCustomAttribute(getShell(), elem)) { 416 fFoldersList.refresh(); 417 fClassPathList.dialogFieldChanged(); } 419 } 420 } 421 422 protected void sourcePageSelectionChanged(DialogField field) { 423 List selected= fFoldersList.getSelectedElements(); 424 fFoldersList.enableButton(IDX_EDIT, canEdit(selected)); 425 fFoldersList.enableButton(IDX_REMOVE, canRemove(selected)); 426 boolean noAttributes= containsOnlyTopLevelEntries(selected); 427 fFoldersList.enableButton(IDX_ADD, noAttributes); 428 } 429 430 private void removeEntry() { 431 List selElements= fFoldersList.getSelectedElements(); 432 for (int i= selElements.size() - 1; i >= 0 ; i--) { 433 Object elem= selElements.get(i); 434 if (elem instanceof CPListElementAttribute) { 435 CPListElementAttribute attrib= (CPListElementAttribute) elem; 436 String key= attrib.getKey(); 437 if (attrib.isBuiltIn()) { 438 Object value= null; 439 if (key.equals(CPListElement.EXCLUSION) || key.equals(CPListElement.INCLUSION)) { 440 value= new Path[0]; 441 } 442 attrib.getParent().setAttribute(key, value); 443 } else { 444 removeCustomAttribute(attrib); 445 } 446 selElements.remove(i); 447 } 448 } 449 if (selElements.isEmpty()) { 450 fFoldersList.refresh(); 451 fClassPathList.dialogFieldChanged(); } else { 453 for (Iterator iter= selElements.iterator(); iter.hasNext();) { 454 CPListElement element= (CPListElement)iter.next(); 455 if (element.getEntryKind() == IClasspathEntry.CPE_SOURCE) { 456 List list= ClasspathModifier.removeFilters(element.getPath(), fCurrJProject, fFoldersList.getElements()); 457 for (Iterator iterator= list.iterator(); iterator.hasNext();) { 458 CPListElement modified= (CPListElement)iterator.next(); 459 fFoldersList.refresh(modified); 460 fFoldersList.expandElement(modified, 3); 461 } 462 } 463 } 464 fFoldersList.removeElements(selElements); 465 } 466 } 467 468 private boolean canRemove(List selElements) { 469 if (selElements.size() == 0) { 470 return false; 471 } 472 for (int i= 0; i < selElements.size(); i++) { 473 Object elem= selElements.get(i); 474 if (elem instanceof CPListElementAttribute) { 475 CPListElementAttribute attrib= (CPListElementAttribute) elem; 476 String key= attrib.getKey(); 477 if (attrib.isBuiltIn()) { 478 if (CPListElement.INCLUSION.equals(key)) { 479 if (((IPath[]) attrib.getValue()).length == 0) { 480 return false; 481 } 482 } else if (CPListElement.EXCLUSION.equals(key)) { 483 if (((IPath[]) attrib.getValue()).length == 0) { 484 return false; 485 } 486 } else if (attrib.getValue() == null) { 487 return false; 488 } 489 } else { 490 if (!canRemoveCustomAttribute(attrib)) { 491 return false; 492 } 493 } 494 } else if (elem instanceof CPListElement) { 495 CPListElement curr= (CPListElement) elem; 496 if (curr.getParentContainer() != null) { 497 return false; 498 } 499 } 500 } 501 return true; 502 } 503 504 private boolean canEdit(List selElements) { 505 if (selElements.size() != 1) { 506 return false; 507 } 508 Object elem= selElements.get(0); 509 if (elem instanceof CPListElement) { 510 CPListElement cp= ((CPListElement)elem); 511 if (cp.getPath().equals(cp.getJavaProject().getPath())) 512 return false; 513 514 return true; 515 } 516 if (elem instanceof CPListElementAttribute) { 517 CPListElementAttribute attrib= (CPListElementAttribute) elem; 518 if (attrib.isBuiltIn()) { 519 return true; 520 } else { 521 return canEditCustomAttribute(attrib); 522 } 523 } 524 return false; 525 } 526 527 private void sourcePageDialogFieldChanged(DialogField field) { 528 if (fCurrJProject == null) { 529 return; 531 } 532 533 if (field == fUseFolderOutputs) { 534 if (!fUseFolderOutputs.isSelected()) { 535 int nFolders= fFoldersList.getSize(); 536 for (int i= 0; i < nFolders; i++) { 537 CPListElement cpe= (CPListElement) fFoldersList.getElement(i); 538 cpe.setAttribute(CPListElement.OUTPUT, null); 539 } 540 } 541 fFoldersList.refresh(); 542 } else if (field == fFoldersList) { 543 updateClasspathList(); 544 } 545 } 546 547 548 private void updateClasspathList() { 549 List srcelements= fFoldersList.getElements(); 550 551 List cpelements= fClassPathList.getElements(); 552 int nEntries= cpelements.size(); 553 int lastRemovePos= nEntries; 555 int afterLastSourcePos= 0; 556 for (int i= nEntries - 1; i >= 0; i--) { 557 CPListElement cpe= (CPListElement)cpelements.get(i); 558 int kind= cpe.getEntryKind(); 559 if (isEntryKind(kind)) { 560 if (!srcelements.remove(cpe)) { 561 cpelements.remove(i); 562 lastRemovePos= i; 563 } else if (lastRemovePos == nEntries) { 564 afterLastSourcePos= i + 1; 565 } 566 } 567 } 568 569 if (!srcelements.isEmpty()) { 570 int insertPos= Math.min(afterLastSourcePos, lastRemovePos); 571 cpelements.addAll(insertPos, srcelements); 572 } 573 574 if (lastRemovePos != nEntries || !srcelements.isEmpty()) { 575 fClassPathList.setElements(cpelements); 576 } 577 } 578 579 582 public List getSelection() { 583 return fFoldersList.getSelectedElements(); 584 } 585 586 589 public void setSelection(List selElements, boolean expand) { 590 fFoldersList.selectElements(new StructuredSelection(selElements)); 591 if (expand) { 592 for (int i= 0; i < selElements.size(); i++) { 593 fFoldersList.expandElement(selElements.get(i), 1); 594 } 595 } 596 } 597 598 601 public boolean isEntryKind(int kind) { 602 return kind == IClasspathEntry.CPE_SOURCE; 603 } 604 605 private void refresh(List insertedElements, List removedElements, List modifiedElements, IPath outputLocation) { 606 fFoldersList.addElements(insertedElements); 607 for (Iterator iter= insertedElements.iterator(); iter.hasNext();) { 608 CPListElement element= (CPListElement)iter.next(); 609 fFoldersList.expandElement(element, 3); 610 } 611 612 fFoldersList.removeElements(removedElements); 613 614 for (Iterator iter= modifiedElements.iterator(); iter.hasNext();) { 615 CPListElement element= (CPListElement)iter.next(); 616 fFoldersList.refresh(element); 617 fFoldersList.expandElement(element, 3); 618 } 619 620 fFoldersList.refresh(); if (!insertedElements.isEmpty()) { 622 fFoldersList.postSetSelection(new StructuredSelection(insertedElements)); 623 } 624 625 fOutputLocationField.setText(outputLocation.makeRelative().toOSString()); 626 } 627 628 631 public void setFocus() { 632 fFoldersList.setFocus(); 633 } 634 635 } 636 | Popular Tags |