/**
   * @param candidates Array of IFeatureModel
   * @param monitor
   * @throws CoreException
   */
  public void doAdd(Object[] candidates) throws CoreException {
    // Category to add features to
    String categoryName = null;
    ISelection selection = fCategoryViewer.getSelection();
    if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
      Object element = ((IStructuredSelection) selection).getFirstElement();
      if (element instanceof ISiteCategoryDefinition) {
        categoryName = ((ISiteCategoryDefinition) element).getName();
      } else if (element instanceof SiteFeatureAdapter) {
        categoryName = ((SiteFeatureAdapter) element).category;
      }
    }
    //
    ISiteFeature[] added = new ISiteFeature[candidates.length];
    for (int i = 0; i < candidates.length; i++) {
      IFeatureModel candidate = (IFeatureModel) candidates[i];
      ISiteFeature child = createSiteFeature(fModel, candidate);
      if (categoryName != null) {
        addCategory(child, categoryName);
      }
      added[i] = child;
    }

    // Update model
    fModel.getSite().addFeatures(added);
    // Select last added feature
    if (added.length > 0) {
      if (categoryName != null) {
        expandCategory(categoryName);
      }
      fCategoryViewer.setSelection(
          new StructuredSelection(new SiteFeatureAdapter(categoryName, added[added.length - 1])),
          true);
    }
  }
 /* (non-Javadoc)
  * @see org.eclipse.ui.forms.AbstractFormPart#setFormInput(java.lang.Object)
  */
 public boolean setFormInput(Object input) {
   if (input instanceof ISiteCategoryDefinition) {
     fCategoryViewer.setSelection(new StructuredSelection(input), true);
     return true;
   }
   if (input instanceof SiteFeatureAdapter) {
     // first, expand the category, otherwise tree will not find the feature
     String category = ((SiteFeatureAdapter) input).category;
     if (category != null) {
       expandCategory(category);
     }
     fCategoryViewer.setSelection(new StructuredSelection(input), true);
     return true;
   }
   return super.setFormInput(input);
 }
  protected void fillContextMenu(IMenuManager manager) {
    Action removeAction =
        new Action(PDEUIMessages.CategorySection_remove) {
          public void run() {
            doGlobalAction(ActionFactory.DELETE.getId());
          }
        };
    removeAction.setEnabled(isEditable());
    manager.add(removeAction);
    getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager);

    ISelection selection = fCategoryViewer.getSelection();
    if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
      final ISiteFeature[] features = getFeaturesFromSelection((IStructuredSelection) selection);
      if (features.length > 0) {
        manager.add(new Separator());
        Action synchronizeAction = new SynchronizePropertiesAction(features, fModel);
        manager.add(synchronizeAction);
        Action buildAction =
            new Action(PDEUIMessages.CategorySection_build) {
              public void run() {
                ((SiteEditor) getPage().getPDEEditor()).handleBuild(features);
              }
            };
        buildAction.setEnabled(isEditable());
        manager.add(buildAction);
      }
    }
  }
 private void handleNewFeature() {
   final Control control = fCategoryViewer.getControl();
   BusyIndicator.showWhile(
       control.getDisplay(),
       new Runnable() {
         public void run() {
           IFeatureModel[] allModels = PDECore.getDefault().getFeatureModelManager().getModels();
           ArrayList<IFeatureModel> newModels = new ArrayList<IFeatureModel>();
           for (int i = 0; i < allModels.length; i++) {
             if (canAdd(allModels[i])) newModels.add(allModels[i]);
           }
           IFeatureModel[] candidateModels =
               newModels.toArray(new IFeatureModel[newModels.size()]);
           FeatureSelectionDialog dialog =
               new FeatureSelectionDialog(
                   fCategoryViewer.getTree().getShell(), candidateModels, true);
           if (dialog.open() == Window.OK) {
             Object[] models = dialog.getResult();
             try {
               doAdd(models);
             } catch (CoreException e) {
               PDEPlugin.log(e);
             }
           }
         }
       });
 }
 private void expandCategory(String category) {
   if (category != null) {
     ISiteCategoryDefinition[] catDefs = fModel.getSite().getCategoryDefinitions();
     for (int i = 0; i < catDefs.length; i++) {
       if (category.equals(catDefs[i].getName())) {
         fCategoryViewer.expandToLevel(catDefs[i], 1);
         break;
       }
     }
   }
 }
 private void handleImportEnvironment() {
   IStructuredSelection sel = (IStructuredSelection) fCategoryViewer.getSelection();
   final ISiteFeature[] selectedFeatures = getFeaturesFromSelection(sel);
   BusyIndicator.showWhile(
       fCategoryTreePart.getControl().getDisplay(),
       new Runnable() {
         public void run() {
           new SynchronizePropertiesAction(selectedFeatures, getModel()).run();
         }
       });
 }
 private void updateButtons() {
   if (!isEditable()) {
     return;
   }
   IStructuredSelection sel = (IStructuredSelection) fCategoryViewer.getSelection();
   fCategoryTreePart.setButtonEnabled(
       BUTTON_BUILD_FEATURE, getFeaturesFromSelection(sel).length > 0);
   int featureCount = fModel.getSite().getFeatures().length;
   fCategoryTreePart.setButtonEnabled(BUTTON_BUILD_ALL, featureCount > 0);
   fCategoryTreePart.setButtonEnabled(BUTTON_IMPORT_ENVIRONMENT, featureCount > 0);
 }
 public boolean doGlobalAction(String actionId) {
   if (actionId.equals(ActionFactory.CUT.getId())) {
     handleRemove();
     return false;
   }
   if (actionId.equals(ActionFactory.PASTE.getId())) {
     doPaste();
     return true;
   }
   if (actionId.equals(ActionFactory.DELETE.getId())) {
     return handleRemove();
   }
   if (actionId.equals(ActionFactory.SELECT_ALL.getId())) {
     fCategoryViewer.getTree().selectAll();
     refresh();
   }
   return false;
 }
 private boolean handleRemoveCategoryDefinition(ISiteCategoryDefinition catDef) {
   try {
     Object[] children =
         ((CategoryContentProvider) fCategoryViewer.getContentProvider()).getChildren(catDef);
     for (int i = 0; i < children.length; i++) {
       SiteFeatureAdapter adapter = (SiteFeatureAdapter) children[i];
       ISiteCategory[] cats = adapter.feature.getCategories();
       for (int j = 0; j < cats.length; j++) {
         if (adapter.category.equals(cats[j].getName()))
           adapter.feature.removeCategories(new ISiteCategory[] {cats[j]});
       }
       if (adapter.feature.getCategories().length == 0) {
         fModel.getSite().removeFeatures(new ISiteFeature[] {adapter.feature});
       }
     }
     fModel.getSite().removeCategoryDefinitions(new ISiteCategoryDefinition[] {catDef});
     return true;
   } catch (CoreException e) {
   }
   return false;
 }
 private void handleAddCategoryDefinition() {
   String name =
       NLS.bind(
           PDEUIMessages.CategorySection_newCategoryName, Integer.toString(++newCategoryCounter));
   while (categoryExists(name)) {
     name =
         NLS.bind(
             PDEUIMessages.CategorySection_newCategoryName,
             Integer.toString(++newCategoryCounter));
   }
   String label =
       NLS.bind(
           PDEUIMessages.CategorySection_newCategoryLabel, Integer.toString(newCategoryCounter));
   ISiteCategoryDefinition categoryDef = fModel.getFactory().createCategoryDefinition();
   try {
     categoryDef.setName(name);
     categoryDef.setLabel(label);
     fModel.getSite().addCategoryDefinitions(new ISiteCategoryDefinition[] {categoryDef});
   } catch (CoreException e) {
     PDEPlugin.logException(e);
   }
   fCategoryViewer.setSelection(new StructuredSelection(categoryDef), true);
 }
  private boolean handleRemove() {
    IStructuredSelection ssel = (IStructuredSelection) fCategoryViewer.getSelection();
    Iterator<?> iterator = ssel.iterator();
    boolean success = true;
    Set<?> removedCategories = new HashSet<Object>();
    while (iterator.hasNext()) {
      Object object = iterator.next();
      if (object == null) continue;
      if (object instanceof ISiteCategoryDefinition) {
        if (!handleRemoveCategoryDefinition((ISiteCategoryDefinition) object)) {
          success = false;
        }
      } else {
        // check if some of features was not removed during category removal
        SiteFeatureAdapter fa = (SiteFeatureAdapter) object;
        if (removedCategories.contains(fa.category)) continue;

        if (!handleRemoveSiteFeatureAdapter(fa)) {
          success = false;
        }
      }
    }
    return success;
  }
 void fireSelection() {
   fCategoryViewer.setSelection(fCategoryViewer.getSelection());
 }
 private void handleBuild() {
   IStructuredSelection sel = (IStructuredSelection) fCategoryViewer.getSelection();
   ((SiteEditor) getPage().getPDEEditor()).handleBuild(getFeaturesFromSelection(sel));
 }
 public void refresh() {
   fCategoryViewer.refresh();
   updateButtons();
   super.refresh();
 }
  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.update.ui.forms.internal.FormSection#createClient(org.eclipse.swt.widgets.Composite,
   *      org.eclipse.update.ui.forms.internal.FormWidgetFactory)
   */
  public void createClient(Section section, FormToolkit toolkit) {
    fModel = (ISiteModel) getPage().getModel();
    fModel.addModelChangedListener(this);

    Composite container = createClientContainer(section, 2, toolkit);
    createViewerPartControl(container, SWT.MULTI, 2, toolkit);
    fCategoryTreePart = getTreePart();
    fCategoryViewer = fCategoryTreePart.getTreeViewer();
    fCategoryViewer.setContentProvider(new CategoryContentProvider());
    fSiteLabelProvider = new SiteLabelProvider();
    fCategoryViewer.setLabelProvider(fSiteLabelProvider);

    fCategoryViewer.setInput(fModel.getSite());
    int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_DEFAULT;
    Transfer[] transfers = new Transfer[] {ModelDataTransfer.getInstance()};
    if (isEditable()) {
      fCategoryViewer.addDropSupport(
          ops,
          transfers,
          new ViewerDropAdapter(fCategoryViewer) {
            public void dragEnter(DropTargetEvent event) {
              Object target = determineTarget(event);
              if (target == null && event.detail == DND.DROP_COPY) {
                event.detail = DND.DROP_MOVE;
              }
              super.dragEnter(event);
            }

            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.viewers.ViewerDropAdapter#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
             */
            public void dragOperationChanged(DropTargetEvent event) {
              Object target = determineTarget(event);
              if (target == null && event.detail == DND.DROP_COPY) {
                event.detail = DND.DROP_MOVE;
              }
              super.dragOperationChanged(event);
            }

            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.viewers.ViewerDropAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
             */
            public void dragOver(DropTargetEvent event) {
              Object target = determineTarget(event);
              if (target == null && event.detail == DND.DROP_COPY) {
                event.detail = DND.DROP_MOVE;
              }
              super.dragOver(event);
            }

            /**
             * Returns the position of the given event's coordinates relative to its target. The
             * position is determined to be before, after, or on the item, based on some threshold
             * value.
             *
             * @param event the event
             * @return one of the <code>LOCATION_* </code> constants defined in this class
             */
            protected int determineLocation(DropTargetEvent event) {
              if (!(event.item instanceof Item)) {
                return LOCATION_NONE;
              }
              Item item = (Item) event.item;
              Point coordinates = new Point(event.x, event.y);
              coordinates = getViewer().getControl().toControl(coordinates);
              if (item != null) {
                Rectangle bounds = getBounds(item);
                if (bounds == null) {
                  return LOCATION_NONE;
                }
              }
              return LOCATION_ON;
            }

            public boolean performDrop(Object data) {
              if (!(data instanceof Object[])) return false;
              Object target = getCurrentTarget();

              int op = getCurrentOperation();
              Object[] objects = (Object[]) data;
              if (objects.length > 0 && objects[0] instanceof SiteFeatureAdapter) {
                if (op == DND.DROP_COPY && target != null) {
                  copyFeature((SiteFeatureAdapter) objects[0], target);
                } else {
                  moveFeature((SiteFeatureAdapter) objects[0], target);
                }
                return true;
              }
              return false;
            }

            public boolean validateDrop(Object target, int operation, TransferData transferType) {
              return (target instanceof ISiteCategoryDefinition || target == null);
            }
          });
    }

    fCategoryViewer.addDragSupport(
        DND.DROP_MOVE | DND.DROP_COPY,
        transfers,
        new DragSourceListener() {
          public void dragStart(DragSourceEvent event) {
            IStructuredSelection ssel = (IStructuredSelection) fCategoryViewer.getSelection();
            if (ssel == null
                || ssel.isEmpty()
                || !(ssel.getFirstElement() instanceof SiteFeatureAdapter)) {
              event.doit = false;
            }
          }

          public void dragSetData(DragSourceEvent event) {
            IStructuredSelection ssel = (IStructuredSelection) fCategoryViewer.getSelection();
            event.data = ssel.toArray();
          }

          public void dragFinished(DragSourceEvent event) {}
        });

    fCategoryTreePart.setButtonEnabled(BUTTON_ADD_CATEGORY, isEditable());
    fCategoryTreePart.setButtonEnabled(BUTTON_ADD_FEATURE, isEditable());
    fCategoryTreePart.setButtonEnabled(BUTTON_BUILD_FEATURE, isEditable());
    fCategoryTreePart.setButtonEnabled(BUTTON_BUILD_ALL, isEditable());

    // fCategoryViewer.expandAll();
    toolkit.paintBordersFor(container);
    section.setClient(container);
    initialize();
  }