private void createCopyAction(final Composite parent) {
    Menu menu = new Menu(parent.getShell(), SWT.POP_UP);
    MenuItem copyAction = new MenuItem(menu, SWT.PUSH);
    copyAction.setText(JFaceResources.getString("copy")); // $NON-NLS-1$
    copyAction.addSelectionListener(
        new SelectionAdapter() {

          /*
           * (non-Javadoc)
           *
           * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
           */
          public void widgetSelected(SelectionEvent e) {
            clipboard = new Clipboard(parent.getDisplay());
            clipboard.setContents(
                new Object[] {prepareCopyString()}, new Transfer[] {TextTransfer.getInstance()});
            super.widgetSelected(e);
          }
        });
    list.setMenu(menu);
  }
  /**
   * Create the composite
   *
   * @param parent
   * @param style
   */
  public AnimateEdgeEditor(Composite parent, int style, AnimateEditor oo, PipAnimateSet aset) {
    super(parent, style);
    this.owner = oo;
    this.animateSet = aset;
    final GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    setLayout(gridLayout);

    buttonFlag = new Button(this, SWT.CHECK);
    buttonFlag.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(final SelectionEvent e) {
            owner.setDirty(true);
          }
        });
    buttonFlag.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
    buttonFlag.setText("包含轮廓定义");

    borderListViewer = new ListViewer(this, SWT.BORDER);
    borderListViewer.addSelectionChangedListener(
        new ISelectionChangedListener() {
          public void selectionChanged(final SelectionChangedEvent arg0) {
            edgeSelectionChanged();
          }
        });
    borderListViewer.setLabelProvider(new ListLabelProvider());
    borderListViewer.setContentProvider(new ContentProvider());
    borderList = borderListViewer.getList();
    final GridData gd_borderList = new GridData(SWT.FILL, SWT.FILL, false, true);
    gd_borderList.widthHint = 237;
    borderList.setLayoutData(gd_borderList);

    final Composite composite = new Composite(this, SWT.NONE);
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    final GridLayout gridLayout_1 = new GridLayout();
    gridLayout_1.numColumns = 4;
    composite.setLayout(gridLayout_1);

    final Label label = new Label(composite, SWT.NONE);
    label.setText("起始动画ID:");

    textFirstAnimate = new Text(composite, SWT.BORDER);
    textFirstAnimate.addModifyListener(
        new ModifyListener() {
          public void modifyText(final ModifyEvent arg0) {
            if (updating) {
              return;
            }
            try {
              EdgeExtension.Edge edge = getEditingEdge();
              int value = Integer.parseInt(textFirstAnimate.getText());
              if (value == -1 || (value >= 0 && value < animateSet.getAnimateCount())) {
                edge.beginAnimateIndex = value;
                owner.setDirty(true);
                textFirstAnimate.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
                return;
              }
            } catch (Exception e) {
            }
            textFirstAnimate.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
          }
        });
    final GridData gd_textFirstAnimate = new GridData(SWT.FILL, SWT.CENTER, true, false);
    textFirstAnimate.setLayoutData(gd_textFirstAnimate);

    final Label label_1 = new Label(composite, SWT.NONE);
    label_1.setText("结束动画ID:");

    textLastAnimate = new Text(composite, SWT.BORDER);
    textLastAnimate.addModifyListener(
        new ModifyListener() {
          public void modifyText(final ModifyEvent arg0) {
            if (updating) {
              return;
            }
            try {
              EdgeExtension.Edge edge = getEditingEdge();
              int value = Integer.parseInt(textLastAnimate.getText());
              if (value == -1 || (value >= 0 && value <= animateSet.getAnimateCount())) {
                edge.endAnimateIndex = value;
                owner.setDirty(true);
                textLastAnimate.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
                return;
              }
            } catch (Exception e) {
            }
            textLastAnimate.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
          }
        });
    final GridData gd_textLastAnimate = new GridData(SWT.FILL, SWT.CENTER, true, false);
    textLastAnimate.setLayoutData(gd_textLastAnimate);

    final Composite editViewerContainer = new Composite(composite, SWT.NONE);
    editViewerContainer.setLayout(new FillLayout());
    final GridData gd_editViewerContainer = new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1);
    editViewerContainer.setLayoutData(gd_editViewerContainer);

    editViewer = new EdgeEditViewer(editViewerContainer, SWT.NONE);
    editViewer.setImageViewerListener(this);

    MenuManager mgr = new MenuManager();
    mgr.add(
        new Action("添加") {
          public void run() {
            onAddEdge();
          }
        });
    mgr.add(
        new Action("删除") {
          public void run() {
            onDeleteEdge();
          }
        });

    Menu menu = mgr.createContextMenu(borderList);
    borderList.setMenu(menu);

    // 设置初始值
    borderListViewer.setInput(new Object());
    EdgeExtension ext = (EdgeExtension) animateSet.findExtension("EDGE");
    if (ext == null) {
      buttonFlag.setSelection(false);
    } else {
      buttonFlag.setSelection(true);
    }
    edgeSelectionChanged();
  }