예제 #1
0
  @Override
  public void performDragOver(DropTargetEvent event) {
    if (!ArtifactTransfer.getInstance().isSupportedType(event.currentDataType)) {
      event.detail = DND.DROP_NONE;
      return;
    }
    final ArtifactData artData = ArtifactTransfer.getInstance().nativeToJava(event.currentDataType);
    if (artData == null) {
      event.detail = DND.DROP_NONE;
      return;
    }
    for (Artifact art : artData.getArtifacts()) {
      if (art.isOfType(CoreArtifactTypes.UniversalGroup)) {
        event.detail = DND.DROP_NONE;
        return;
      }
    }
    Tree tree = treeViewer.getTree();
    TreeItem dragOverTreeItem = tree.getItem(treeViewer.getTree().toControl(event.x, event.y));

    event.feedback = DND.FEEDBACK_EXPAND;
    event.detail = DND.DROP_NONE;

    // Set as COPY if drag item over group (copy versus move will be determined on drop
    if (dragOverTreeItem != null
        && ((GroupExplorerItem) dragOverTreeItem.getData()).isUniversalGroup()) {
      event.detail = DND.DROP_COPY;
      tree.setInsertMark(null, false);
    }
    // Handle re-ordering within same group
    else if (dragOverTreeItem != null
        && !((GroupExplorerItem) dragOverTreeItem.getData()).isUniversalGroup()) {
      GroupExplorerItem dragOverGroupItem = (GroupExplorerItem) dragOverTreeItem.getData();
      IStructuredSelection selectedItem = (IStructuredSelection) treeViewer.getSelection();
      Object obj = selectedItem.getFirstElement();
      if (obj instanceof GroupExplorerItem) {
        GroupExplorerItem droppingGroupItem = (GroupExplorerItem) obj;

        // the group to move must belong to the same group as the member to insert before/after
        if (dragOverGroupItem.getParentItem().equals(droppingGroupItem.getParentItem())) {
          if (isFeedbackAfter) {
            event.feedback = DND.FEEDBACK_INSERT_AFTER;
          } else {
            event.feedback = DND.FEEDBACK_INSERT_BEFORE;
          }
          event.detail = DND.DROP_MOVE;
        }
      } else {
        if (isFeedbackAfter) {
          event.feedback = DND.FEEDBACK_INSERT_AFTER;
        } else {
          event.feedback = DND.FEEDBACK_INSERT_BEFORE;
        }
        event.detail = DND.DROP_COPY;
      }
    } else {
      tree.setInsertMark(null, false);
    }
  }
/**
 * The <code>ArtifactTransfer</code> class is used to transfer an array of <code>Artifact</code>s from one part to
 * another in a drag and drop operation or a cut, copy, paste action.
 * <p>
 * In every drag and drop operation there is a <code>DragSource</code> and a <code>DropTarget</code>. When a drag occurs
 * a <code>Transfer</code> is used to marshall the drag data from the source into a byte array. If a drop occurs another
 * <code>Transfer</code> is used to marshall the byte array into drop data for the target.
 * </p>
 * <p>
 * When a <code>CutAction</code> or a <code>CopyAction</code> is performed, this transfer is used to place references to
 * the selected resources on the <code>Clipboard</code>. When a <code>PasteAction</code> is performed, the references on
 * the clipboard are used to move or copy the resources to the selected destination.
 * </p>
 * <p>
 * This class can be used for a <code>Viewer<code> or an SWT component directly.
 * A singleton is provided which may be serially reused (see <code>getInstance</code>). It is not intended to be
 * subclassed.
 * </p>
 *
 * @see org.eclipse.jface.viewers.StructuredViewer
 * @see org.eclipse.swt.dnd.DropTarget
 * @see org.eclipse.swt.dnd.DragSource
 * @author Robert A. Fisher
 */
public class ArtifactTransfer extends ByteArrayTransfer {

  /** Singleton instance. */
  private static final ArtifactTransfer instance = new ArtifactTransfer();

  // Create a unique ID to make sure that different Eclipse
  // applications use different "types" of <code>ResourceTransfer</code>
  private static final String TYPE_NAME =
      "artifact-transfer-format:"
          + System.currentTimeMillis()
          + ":"
          + instance.hashCode(); // $NON-NLS-2$//$NON-NLS-1$

  private static final int TYPEID = registerType(TYPE_NAME);

  public static ArtifactTransfer getInstance() {
    return instance;
  }

  @Override
  protected int[] getTypeIds() {
    return new int[] {TYPEID};
  }

  @Override
  protected String[] getTypeNames() {
    return new String[] {TYPE_NAME};
  }

  @Override
  protected void javaToNative(Object data, TransferData transferData) {
    if (!(data instanceof ArtifactData)) {
      return;
    }

    ArtifactData artData = (ArtifactData) data;
    /**
     * The resource serialization format is: (int) number of artifacts Then, the following for each
     * resource: (int) artID (int) tagID Then the following (int) urlLength (int) sourceLength
     * (chars) url (chars) source
     */
    try {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      DataOutputStream dataOut = new DataOutputStream(out);

      // write the number of resources
      dataOut.writeInt(artData.getArtifacts().length);

      for (Artifact artifact : artData.getArtifacts()) {
        writeArtifact(dataOut, artifact);
      }
      dataOut.writeInt(artData.getUrl().length());
      dataOut.writeInt(artData.getSource().length());
      dataOut.writeChars(artData.getUrl());
      dataOut.writeChars(artData.getSource());

      // cleanup
      dataOut.close();
      out.close();
      byte[] bytes = out.toByteArray();
      super.javaToNative(bytes, transferData);
    } catch (Exception e) {
      // it's best to send nothing if there were problems
    }
  }

  @Override
  public ArtifactData nativeToJava(TransferData transferData) {
    /**
     * The resource serialization format is: (int) number of artifacts Then, the following for each
     * resource: (int) artID (int) tagID
     */
    byte[] bytes = (byte[]) super.nativeToJava(transferData);
    if (bytes == null) {
      return null;
    }
    DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
    try {
      int count = in.readInt();
      Artifact[] artifacts = new Artifact[count];
      for (int i = 0; i < count; i++) {
        artifacts[i] = readArtifact(in);
      }
      int urlLength = in.readInt();
      int sourceLength = in.readInt();
      String url = "";
      for (int x = 0; x < urlLength; x++) {
        url += in.readChar();
      }
      String source = "";
      for (int x = 0; x < sourceLength; x++) {
        source += in.readChar();
      }
      return new ArtifactData(artifacts, url, source);
    } catch (Exception ex) {
      OseeLog.log(Activator.class, Level.SEVERE, ex);
      return null;
    }
  }

  /** Reads a resource from the given stream. */
  private Artifact readArtifact(DataInputStream dataIn) throws OseeCoreException, IOException {
    int artID = dataIn.readInt();
    int branchId = dataIn.readInt();
    return ArtifactQuery.getArtifactFromId(artID, BranchManager.getBranch(branchId));
  }

  /**
   * Writes the given resource to the given stream.
   *
   * @throws OseeCoreException
   */
  private void writeArtifact(DataOutputStream dataOut, Artifact artifact)
      throws IOException, OseeCoreException {
    dataOut.writeInt(artifact.getArtId());
    dataOut.writeInt(artifact.getFullBranch().getId());
  }
}