private boolean handleRemoveSiteFeatureAdapter(SiteFeatureAdapter adapter) {
   try {
     ISiteFeature feature = adapter.feature;
     if (adapter.category == null) {
       fModel.getSite().removeFeatures(new ISiteFeature[] {feature});
     } else {
       removeCategory(feature, adapter.category);
       if (feature.getCategories().length == 0)
         fModel.getSite().removeFeatures(new ISiteFeature[] {feature});
     }
     return true;
   } catch (CoreException e) {
   }
   return false;
 }
  /**
   * @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);
    }
  }
 private boolean categoryExists(String name) {
   ISiteCategoryDefinition[] defs = fModel.getSite().getCategoryDefinitions();
   for (int i = 0; i < defs.length; i++) {
     ISiteCategoryDefinition def = defs[i];
     String dname = def.getName();
     if (dname != null && dname.equals(name)) return true;
   }
   return false;
 }
 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 boolean canAdd(IFeatureModel candidate) {
    ISiteFeature[] features = fModel.getSite().getFeatures();
    IFeature cfeature = candidate.getFeature();

    for (int i = 0; i < features.length; i++) {
      ISiteFeature bfeature = features[i];
      if (bfeature.getId().equals(cfeature.getId())
          && bfeature.getVersion().equals(cfeature.getVersion())) return false;
    }
    return true;
  }
 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);
 }
 private ISiteFeature findRealFeature(SiteFeatureAdapter adapter) {
   ISiteFeature featureCopy = adapter.feature;
   ISiteFeature[] features = fModel.getSite().getFeatures();
   for (int i = 0; i < features.length; i++) {
     if (features[i].getId().equals(featureCopy.getId())
         && features[i].getVersion().equals(featureCopy.getVersion())) {
       return features[i];
     }
   }
   return null;
 }
 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;
 }
 /*
  * (non-Javadoc)
  *
  * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object,
  *      java.lang.Object[])
  */
 protected void doPaste(Object target, Object[] objects) {
   try {
     for (int i = 0; i < objects.length; i++) {
       if (objects[i] instanceof SiteFeatureAdapter) {
         copyFeature((SiteFeatureAdapter) objects[i], target);
       } else if (objects[i] instanceof ISiteCategoryDefinition) {
         fModel
             .getSite()
             .addCategoryDefinitions(
                 new ISiteCategoryDefinition[] {(ISiteCategoryDefinition) objects[i]});
       }
     }
   } catch (CoreException e) {
   }
 }
 private void copyFeature(SiteFeatureAdapter adapter, Object target) {
   ISiteFeature feature = findRealFeature(adapter);
   if (feature == null) {
     try {
       feature = copySiteFeature(fModel, adapter.feature);
       fModel.getSite().addFeatures(new ISiteFeature[] {feature});
     } catch (CoreException ce) {
       return;
     }
   }
   /*
    * if (adapter.category == null) { moveFeature(adapter, target); } else
    */ if (target != null && target instanceof ISiteCategoryDefinition) {
     addCategory(feature, ((ISiteCategoryDefinition) target).getName());
   }
 }
 /*
  * (non-Javadoc)
  *
  * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object,
  *      java.lang.Object[])
  */
 protected boolean canPaste(Object target, Object[] objects) {
   if (target == null || target instanceof ISiteCategoryDefinition) {
     for (int i = 0; i < objects.length; i++) {
       if (objects[i] instanceof SiteFeatureAdapter) return true;
       if (objects[i] instanceof ISiteCategoryDefinition) {
         String name = ((ISiteCategoryDefinition) objects[i]).getName();
         ISiteCategoryDefinition[] defs = fModel.getSite().getCategoryDefinitions();
         for (int j = 0; j < defs.length; j++) {
           ISiteCategoryDefinition def = defs[j];
           String dname = def.getName();
           if (dname != null && dname.equals(name)) return false;
         }
         return true;
       }
     }
   }
   return false;
 }
 protected void buttonSelected(int index) {
   switch (index) {
     case BUTTON_ADD_CATEGORY:
       handleAddCategoryDefinition();
       break;
     case BUTTON_ADD_FEATURE:
       handleNewFeature();
       break;
     case BUTTON_BUILD_FEATURE:
       handleBuild();
       break;
     case BUTTON_BUILD_ALL:
       ((SiteEditor) getPage().getPDEEditor()).handleBuild(fModel.getSite().getFeatures());
       break;
     case BUTTON_IMPORT_ENVIRONMENT:
       handleImportEnvironment();
   }
 }
 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);
 }
  /*
   * (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();
  }