1 11 12 package org.eclipse.pde.internal.ui.editor.build; 13 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 16 import java.util.Set ; 17 import java.util.TreeSet ; 18 import java.util.Vector ; 19 20 import org.eclipse.core.resources.IFile; 21 import org.eclipse.core.resources.IFolder; 22 import org.eclipse.core.resources.IProject; 23 import org.eclipse.core.resources.IResource; 24 import org.eclipse.core.resources.IResourceChangeEvent; 25 import org.eclipse.core.resources.IResourceChangeListener; 26 import org.eclipse.core.resources.IResourceDelta; 27 import org.eclipse.core.resources.IResourceDeltaVisitor; 28 import org.eclipse.core.runtime.CoreException; 29 import org.eclipse.core.runtime.IPath; 30 import org.eclipse.jface.action.IMenuListener; 31 import org.eclipse.jface.action.IMenuManager; 32 import org.eclipse.jface.action.MenuManager; 33 import org.eclipse.jface.viewers.CheckStateChangedEvent; 34 import org.eclipse.jface.viewers.CheckboxTreeViewer; 35 import org.eclipse.jface.viewers.ICheckStateListener; 36 import org.eclipse.jface.viewers.ISelection; 37 import org.eclipse.jface.viewers.IStructuredSelection; 38 import org.eclipse.jface.viewers.ITreeContentProvider; 39 import org.eclipse.pde.core.IModelChangedEvent; 40 import org.eclipse.pde.core.IModelChangedListener; 41 import org.eclipse.pde.core.build.IBuild; 42 import org.eclipse.pde.core.build.IBuildEntry; 43 import org.eclipse.pde.core.build.IBuildModel; 44 import org.eclipse.pde.internal.build.IBuildPropertiesConstants; 45 import org.eclipse.pde.internal.ui.PDEPlugin; 46 import org.eclipse.pde.internal.ui.editor.FormLayoutFactory; 47 import org.eclipse.pde.internal.ui.editor.PDEFormPage; 48 import org.eclipse.pde.internal.ui.editor.TableSection; 49 import org.eclipse.pde.internal.ui.editor.context.InputContext; 50 import org.eclipse.pde.internal.ui.elements.DefaultContentProvider; 51 import org.eclipse.swt.SWT; 52 import org.eclipse.swt.custom.BusyIndicator; 53 import org.eclipse.swt.layout.GridData; 54 import org.eclipse.swt.widgets.Composite; 55 import org.eclipse.swt.widgets.Control; 56 import org.eclipse.swt.widgets.Display; 57 import org.eclipse.swt.widgets.Menu; 58 import org.eclipse.ui.forms.widgets.FormToolkit; 59 import org.eclipse.ui.forms.widgets.Section; 60 import org.eclipse.ui.model.WorkbenchLabelProvider; 61 62 public abstract class BuildContentsSection extends TableSection 63 implements 64 IModelChangedListener, 65 IResourceChangeListener, 66 IResourceDeltaVisitor { 67 68 protected CheckboxTreeViewer fTreeViewer; 69 private boolean fDoRefresh = false; 70 protected IProject fProject; 71 protected IBuildModel fBuildModel; 72 protected IResource fOriginalResource, fParentResource; 73 protected boolean isChecked; 74 75 public class TreeContentProvider extends DefaultContentProvider 76 implements 77 ITreeContentProvider { 78 79 public Object [] getElements(Object parent) { 80 if (parent instanceof IProject) { 81 try { 82 return ((IProject) parent).members(); 83 } catch (CoreException e) { 84 PDEPlugin.logException(e); 85 } 86 } 87 return new Object [0]; 88 } 89 90 93 public Object [] getChildren(Object parent) { 94 try { 95 if (parent instanceof IFolder) 96 return ((IFolder) parent).members(); 97 } catch (CoreException e) { 98 PDEPlugin.logException(e); 99 } 100 return new Object [0]; 101 } 102 103 public Object [] getFolderChildren(Object parent) { 104 IResource[] members = null; 105 try { 106 if (!(parent instanceof IFolder)) 107 return new Object [0]; 108 members = ((IFolder) parent).members(); 109 ArrayList results = new ArrayList (); 110 for (int i = 0; i < members.length; i++) { 111 if ((members[i].getType() == IResource.FOLDER)) { 112 results.add(members[i]); 113 } 114 } 115 return results.toArray(); 116 } catch (CoreException e) { 117 PDEPlugin.logException(e); 118 } 119 return new Object [0]; 120 } 121 122 125 public Object getParent(Object element) { 126 if (element != null && element instanceof IResource) { 127 return ((IResource) element).getParent(); 128 } 129 return null; 130 } 131 132 135 public boolean hasChildren(Object element) { 136 if (element instanceof IFolder) 137 return getChildren(element).length > 0; 138 return false; 139 } 140 } 141 protected void createViewerPartControl(Composite parent, int style, int span, FormToolkit toolkit) { 142 MenuManager popupMenuManager = new MenuManager(); 143 IMenuListener listener = new IMenuListener() { 144 public void menuAboutToShow(IMenuManager mng) { 145 fillContextMenu(mng); 146 } 147 }; 148 popupMenuManager.addMenuListener(listener); 149 popupMenuManager.setRemoveAllWhenShown(true); 150 Control control = fTreeViewer.getControl(); 151 Menu menu = popupMenuManager.createContextMenu(control); 152 control.setMenu(menu); 153 } 154 157 protected void fillContextMenu(IMenuManager manager) { 158 manager.add(getPage().getPDEEditor().getContributor().getRevertAction()); 159 getPage().getPDEEditor().getContributor().contextMenuAboutToShow( 160 manager, false); 161 } 162 private IBuildModel getBuildModel() { 163 InputContext context = getPage().getPDEEditor().getContextManager() 164 .findContext(BuildInputContext.CONTEXT_ID); 165 return (IBuildModel) context.getModel(); 166 } 167 168 public BuildContentsSection(PDEFormPage page, Composite parent) { 169 super(page, parent, Section.DESCRIPTION, new String [0]); 170 PDEPlugin.getWorkspace().addResourceChangeListener(this); 171 } 172 173 public void createClient(final Section section, FormToolkit toolkit) { 174 Composite container = createClientContainer(section, 2, toolkit); 175 fBuildModel = getBuildModel(); 176 if (fBuildModel.getUnderlyingResource() != null) 177 fProject = fBuildModel.getUnderlyingResource().getProject(); 178 179 fTreeViewer = new CheckboxTreeViewer(toolkit.createTree(container, 180 SWT.CHECK)); 181 fTreeViewer.setContentProvider(new TreeContentProvider()); 182 fTreeViewer.setLabelProvider(new WorkbenchLabelProvider()); 183 fTreeViewer.setAutoExpandLevel(0); 184 fTreeViewer.addCheckStateListener(new ICheckStateListener() { 185 186 public void checkStateChanged(final CheckStateChangedEvent event) { 187 final Object element = event.getElement(); 188 BusyIndicator.showWhile(section.getDisplay(), new Runnable () { 189 190 public void run() { 191 if (element instanceof IFile) { 192 IFile file = (IFile) event.getElement(); 193 handleCheckStateChanged(file, event.getChecked()); 194 } else if (element instanceof IFolder) { 195 IFolder folder = (IFolder) event.getElement(); 196 handleCheckStateChanged(folder, event.getChecked()); 197 } 198 } 199 }); 200 } 201 }); 202 GridData gd = new GridData(GridData.FILL_BOTH); 203 gd.heightHint = 100; 204 gd.widthHint = 100; 205 fTreeViewer.getTree().setLayoutData(gd); 206 initialize(); 207 toolkit.paintBordersFor(container); 208 createViewerPartControl(container, SWT.FULL_SELECTION, 2, toolkit); 209 section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1)); 210 section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 211 section.setClient(container); 212 } 213 214 public void enableSection(boolean enable) { 215 fTreeViewer.getTree().setEnabled(enable); 216 } 217 218 protected void handleCheckStateChanged(IResource resource, boolean checked) { 219 fOriginalResource = resource; 220 isChecked = checked; 221 boolean wasTopParentChecked = fTreeViewer.getChecked(fOriginalResource 222 .getParent()); 223 if (!isChecked) { 224 resource = handleAllUnselected(resource, resource.getName()); 225 } 226 fParentResource = resource; 227 handleBuildCheckStateChange(wasTopParentChecked); 228 } 229 230 protected IResource handleAllUnselected(IResource resource, String name) { 231 IResource parent = resource.getParent(); 232 if (parent == resource.getProject()) { 233 return resource; 234 } 235 try { 236 boolean uncheck = true; 237 IResource[] members = ((IFolder) parent).members(); 238 for (int i = 0; i < members.length; i++) { 239 if (fTreeViewer.getChecked(members[i]) 240 && !members[i].getName().equals(name)) 241 uncheck = false; 242 } 243 if (uncheck) { 244 return handleAllUnselected(parent, parent.getName()); 245 } 246 return resource; 247 } catch (CoreException e) { 248 PDEPlugin.logException(e); 249 return null; 250 } 251 } 252 253 protected void setChildrenGrayed(IResource folder, boolean isGray) { 254 fTreeViewer.setGrayed(folder, isGray); 255 if (((TreeContentProvider) fTreeViewer.getContentProvider()) 256 .hasChildren(folder)) { 257 Object [] members = ((TreeContentProvider) fTreeViewer 258 .getContentProvider()).getFolderChildren(folder); 259 for (int i = 0; i < members.length; i++) { 260 setChildrenGrayed((IFolder) members[i], isGray); 261 } 262 } 263 } 264 265 protected void setParentsChecked(IResource resource) { 266 if (resource.getParent() != resource.getProject()) { 267 fTreeViewer.setChecked(resource.getParent(), true); 268 setParentsChecked(resource.getParent()); 269 } 270 } 271 272 280 protected abstract void deleteFolderChildrenFromEntries(IFolder folder); 281 282 protected void initializeCheckState() { 283 uncheckAll(); 284 } 285 286 protected void initializeCheckState(final IBuildEntry includes, 287 final IBuildEntry excludes) { 288 fTreeViewer.getTree().getDisplay().asyncExec(new Runnable () { 289 290 public void run() { 291 BusyIndicator.showWhile(Display.getCurrent(), new Runnable () { 293 294 public void run() { 295 if (fTreeViewer.getTree().isDisposed()) return; 296 Vector fileExt = new Vector (); 297 String [] inclTokens, exclTokens = new String [0]; 298 if (fProject == null || includes == null) 299 return; 300 inclTokens = includes.getTokens(); 301 if (excludes != null) 302 exclTokens = excludes.getTokens(); 303 Set temp = new TreeSet (); 304 for (int i = 0; i < inclTokens.length; i++) 305 temp.add(inclTokens[i]); 306 for (int i = 0; i < exclTokens.length; i++) 307 temp.add(exclTokens[i]); 308 Iterator iter = temp.iterator(); 309 while (iter.hasNext()) { 310 String resource = iter.next().toString(); 311 boolean isIncluded = includes.contains(resource); 312 if (resource.equals(".") || resource.equals("./") || resource.equals(".\\")) { } else if (resource.lastIndexOf(IPath.SEPARATOR) == resource 315 .length() - 1) { 316 IFolder folder = fProject.getFolder(resource); 317 if (!folder.exists()) 318 continue; 319 fTreeViewer.setSubtreeChecked(folder, isIncluded); 320 fTreeViewer.setParentsGrayed(folder, true); 321 if (isIncluded) { 322 setParentsChecked(folder); 323 fTreeViewer.setGrayed(folder, false); 324 } 325 } else if (resource.startsWith("*.")) { if (isIncluded) 327 fileExt.add(resource.substring(2)); 328 } else { 329 IFile file = fProject.getFile(resource); 330 if (!file.exists()) 331 continue; 332 fTreeViewer.setChecked(file, isIncluded); 333 fTreeViewer.setParentsGrayed(file, true); 334 if (isIncluded) { 335 fTreeViewer.setGrayed(file, false); 336 setParentsChecked(file); 337 } 338 } 339 } 340 if (fileExt.size() == 0) 341 return; 342 try { 343 IResource[] members = fProject.members(); 344 for (int i = 0; i < members.length; i++) { 345 if (!(members[i] instanceof IFolder) 346 && (fileExt.contains(members[i] 347 .getFileExtension()))) { 348 fTreeViewer.setChecked(members[i], includes 349 .contains("*." + members[i].getFileExtension())); 351 } 352 } 353 } catch (CoreException e) { 354 PDEPlugin.logException(e); 355 } 356 } 357 }); 358 } 359 }); 360 } 361 362 protected abstract void handleBuildCheckStateChange( 363 boolean wasTopParentChecked); 364 365 protected void handleCheck(IBuildEntry includes, IBuildEntry excludes, 366 String resourceName, IResource resource, 367 boolean wasTopParentChecked, String PROPERTY_INCLUDES) { 368 369 try { 370 if (includes == null) { 371 includes = fBuildModel.getFactory().createEntry( 372 PROPERTY_INCLUDES); 373 IBuild build = fBuildModel.getBuild(); 374 build.add(includes); 375 } 376 if ((!wasTopParentChecked && !includes.contains(resourceName)) 377 || isValidIncludeEntry(includes, excludes, resource, 378 resourceName)) { 379 includes.addToken(resourceName); 380 } 381 if (excludes != null && excludes.contains(resourceName)) 382 excludes.removeToken(resourceName); 383 } catch (CoreException e) { 384 PDEPlugin.logException(e); 385 } 386 } 387 388 protected boolean isValidIncludeEntry(IBuildEntry includes, 389 IBuildEntry excludes, IResource resource, String resourceName) { 390 if (excludes == null) 391 return true; 392 IPath resPath = resource.getProjectRelativePath(); 393 while (resPath.segmentCount() > 1) { 394 resPath = resPath.removeLastSegments(1); 395 if (includes.contains(resPath.toString() + IPath.SEPARATOR)) 396 return false; 397 else if (excludes != null 398 && excludes.contains(resPath.toString() + IPath.SEPARATOR)) 399 return true; 400 } 401 return !excludes.contains(resourceName); 402 } 403 404 protected void handleUncheck(IBuildEntry includes, IBuildEntry excludes, 405 String resourceName, IResource resource, String PROPERTY_EXCLUDES) { 406 407 try { 408 if (fTreeViewer.getChecked(resource.getParent())) { 409 if (excludes == null) { 410 excludes = fBuildModel.getFactory().createEntry( 411 PROPERTY_EXCLUDES); 412 IBuild build = fBuildModel.getBuild(); 413 build.add(excludes); 414 } 415 if (!excludes.contains(resourceName) 416 && (includes != null 417 ? !includes.contains(resourceName) 418 : true)) 419 excludes.addToken(resourceName); 420 } 421 if (includes != null) { 422 if (includes.contains(resourceName)) 423 includes.removeToken(resourceName); 424 if (includes.contains("*." + resource.getFileExtension())) { IResource[] members = fProject.members(); 426 for (int i = 0; i < members.length; i++) { 427 if (!(members[i] instanceof IFolder) 428 && !members[i].getName().equals( 429 resource.getName()) 430 && (resource.getFileExtension() 431 .equals(members[i].getFileExtension()))) { 432 includes.addToken(members[i].getName()); 433 } 434 IBuildEntry[] libraries = BuildUtil 435 .getBuildLibraries(fBuildModel.getBuild() 436 .getBuildEntries()); 437 if (resource.getFileExtension().equals("jar") && libraries.length != 0) { 439 for (int j = 0; j < libraries.length; j++) { 440 String libName = libraries[j].getName() 441 .substring(7); 442 IPath path = fProject.getFile(libName) 443 .getProjectRelativePath(); 444 if (path.segmentCount() == 1 445 && !includes.contains(libName) 446 && !libName.equals(resource.getName())) 447 includes.addToken(libName); 448 } 449 } 450 } 451 includes.removeToken("*." + resource.getFileExtension()); } 453 } 454 } catch (CoreException e) { 455 PDEPlugin.logException(e); 456 } 457 } 458 459 protected String getResourceFolderName(String resourceName) { 460 return resourceName + IPath.SEPARATOR; 461 } 462 463 471 protected String handleResourceFolder(IResource resource, 472 String resourceName) { 473 if (resource instanceof IFolder) { 474 deleteFolderChildrenFromEntries((IFolder) resource); 475 return getResourceFolderName(resourceName); 476 } 477 return resourceName; 478 } 479 480 public void initialize() { 481 if (fTreeViewer.getInput() == null) { 482 fTreeViewer.setUseHashlookup(true); 483 fTreeViewer.setInput(fProject); 484 } 485 fBuildModel.addModelChangedListener(this); 486 } 487 488 public void dispose() { 489 fBuildModel.removeModelChangedListener(this); 490 PDEPlugin.getWorkspace().removeResourceChangeListener(this); 491 super.dispose(); 492 } 493 494 protected void deleteEmptyEntries() { 495 IBuild build = fBuildModel.getBuild(); 496 IBuildEntry[] entries = { 497 build.getEntry(IBuildPropertiesConstants.PROPERTY_BIN_EXCLUDES), 498 build.getEntry(IBuildPropertiesConstants.PROPERTY_BIN_INCLUDES), 499 build.getEntry(IBuildPropertiesConstants.PROPERTY_SRC_EXCLUDES), 500 build.getEntry(IBuildPropertiesConstants.PROPERTY_SRC_INCLUDES)}; 501 try { 502 for (int i = 0; i < entries.length; i++) { 503 if (entries[i] != null && entries[i].getTokens().length == 0) 504 build.remove(entries[i]); 505 } 506 } catch (CoreException e) { 507 PDEPlugin.logException(e); 508 } 509 } 510 511 public CheckboxTreeViewer getTreeViewer() { 512 return fTreeViewer; 513 } 514 515 protected ISelection getViewerSelection() { 516 return getTreeViewer().getSelection(); 517 } 518 519 public void refresh() { 520 initializeCheckState(); 521 super.refresh(); 522 } 523 524 public void uncheckAll() { 525 fTreeViewer.setCheckedElements(new Object [0]); 526 } 527 528 protected void removeChildren(IBuildEntry entry, String parentFolder) { 529 try { 530 if (entry != null) { 531 String [] tokens = entry.getTokens(); 532 for (int i = 0; i < tokens.length; i++) { 533 if (tokens[i].indexOf(IPath.SEPARATOR) != -1 534 && tokens[i].startsWith(parentFolder) 535 && !tokens[i].equals(parentFolder)) { 536 entry.removeToken(tokens[i]); 537 } 538 } 539 } 540 } catch (CoreException e) { 541 PDEPlugin.logException(e); 542 } 543 } 544 545 public void resourceChanged(IResourceChangeEvent event) { 546 if (fTreeViewer.getControl().isDisposed()) 547 return; 548 fDoRefresh = false; 549 IResourceDelta delta = event.getDelta(); 550 try { 551 if (delta != null) 552 delta.accept(this); 553 if (fDoRefresh) { 554 asyncRefresh(); 555 fDoRefresh = false; 556 } 557 } catch (CoreException e) { 558 } 559 } 560 561 public boolean visit(IResourceDelta delta) throws CoreException { 562 IResource resource = delta.getResource(); 563 IProject project = fBuildModel.getUnderlyingResource().getProject(); 564 565 if ((resource instanceof IFile || resource instanceof IFolder) 566 && resource.getProject().equals(project)) { 567 if (delta.getKind() == IResourceDelta.ADDED 568 || delta.getKind() == IResourceDelta.REMOVED) { 569 fDoRefresh = true; 570 return false; 571 } 572 } else if (resource instanceof IProject && ((IProject)resource).equals(project)) { 573 return delta.getKind() != IResourceDelta.REMOVED; 574 } 575 return true; 576 } 577 578 private void asyncRefresh() { 579 Control control = fTreeViewer.getControl(); 580 if (!control.isDisposed()) { 581 control.getDisplay().asyncExec(new Runnable () { 582 583 public void run() { 584 if (!fTreeViewer.getControl().isDisposed()) { 585 fTreeViewer.refresh(true); 586 initializeCheckState(); 587 } 588 } 589 }); 590 } 591 } 592 593 598 protected void selectionChanged(IStructuredSelection selection) { 599 getPage().getPDEEditor().setSelection(selection); 600 601 } 602 603 public void modelChanged(IModelChangedEvent event) { 604 605 if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) { 606 markStale(); 607 } 608 Object changeObject = event.getChangedObjects()[0]; 609 610 if (!(changeObject instanceof IBuildEntry && (((IBuildEntry) changeObject) 611 .getName().equals( 612 IBuildPropertiesConstants.PROPERTY_BIN_EXCLUDES) 613 || ((IBuildEntry) changeObject).getName().equals( 614 IBuildPropertiesConstants.PROPERTY_BIN_INCLUDES) 615 || ((IBuildEntry) changeObject).getName().equals( 616 IBuildPropertiesConstants.PROPERTY_SRC_EXCLUDES) || ((IBuildEntry) changeObject) 617 .getName().equals( 618 IBuildPropertiesConstants.PROPERTY_SRC_INCLUDES)))) 619 return; 620 621 if ((fParentResource == null && fOriginalResource != null) 622 || (fOriginalResource == null && fParentResource != null)) { 623 initializeCheckState(); 624 return; 625 } 626 if ((fParentResource == null && fOriginalResource == null) 627 || (event.getChangedProperty() != null && event 628 .getChangedProperty() 629 .equals(IBuildPropertiesConstants.PROPERTY_BIN_INCLUDES))) { 630 631 return; 632 } 633 634 fTreeViewer.setChecked(fParentResource, isChecked); 635 fTreeViewer.setGrayed(fOriginalResource, false); 636 fTreeViewer.setParentsGrayed(fParentResource, true); 637 setParentsChecked(fParentResource); 638 fTreeViewer.setGrayed(fParentResource, false); 639 if (fParentResource instanceof IFolder) { 640 fTreeViewer.setSubtreeChecked(fParentResource, isChecked); 641 setChildrenGrayed(fParentResource, false); 642 } 643 while (!fOriginalResource.equals(fParentResource)) { 644 fTreeViewer.setChecked(fOriginalResource, isChecked); 645 fOriginalResource = fOriginalResource.getParent(); 646 } 647 fParentResource = null; 648 fOriginalResource = null; 649 } 650 } 651 | Popular Tags |