/**
   * Callback that is invoked when a property in the compare configuration ( {@link
   * #getCompareConfiguration()} changes.
   *
   * @param event the property change event
   * @since 3.3
   */
  protected void handlePropertyChangeEvent(PropertyChangeEvent event) {

    String key = event.getProperty();

    if (key.equals(ICompareUIConstants.PROP_ANCESTOR_VISIBLE)) {
      fAncestorVisible =
          Utilities.getBoolean(
              getCompareConfiguration(),
              ICompareUIConstants.PROP_ANCESTOR_VISIBLE,
              fAncestorVisible);
      fComposite.layout(true);

      updateCursor(fLeftLabel, VERTICAL);
      updateCursor(fDirectionLabel, HORIZONTAL | VERTICAL);
      updateCursor(fRightLabel, VERTICAL);

      return;
    }

    if (key.equals(ICompareUIConstants.PROP_IGNORE_ANCESTOR)) {
      setAncestorVisibility(
          false,
          !Utilities.getBoolean(
              getCompareConfiguration(), ICompareUIConstants.PROP_IGNORE_ANCESTOR, false));
      return;
    }
  }
    public void mouseDown(MouseEvent e) {
      Composite parent = fControl.getParent();

      Point s = parent.getSize();
      Point as = fAncestorLabel.getSize();
      Point ys = fLeftLabel.getSize();
      Point ms = fRightLabel.getSize();

      fWidth1 = ys.x;
      fWidth2 = ms.x;
      fHeight1 = fLeftLabel.getLocation().y - as.y;
      fHeight2 = s.y - (fLeftLabel.getLocation().y + ys.y);

      fX = e.x;
      fY = e.y;
      fIsDown = true;
    }
  /**
   * Builds the SWT controls for the three areas of a compare/merge viewer.
   *
   * <p>Calls the hooks <code>createControls</code> and <code>createToolItems</code> to let
   * subclasses build the specific content areas and to add items to an enclosing toolbar.
   *
   * <p>This method must only be called in the constructor of subclasses.
   *
   * @param parent the parent control
   * @return the new control
   */
  protected final Control buildControl(Composite parent) {

    fComposite =
        new Composite(parent, fStyles | SWT.LEFT_TO_RIGHT) { // we
          // force
          // a
          // specific
          // direction
          public boolean setFocus() {
            return ContentMergeViewer.this.handleSetFocus();
          }
        };
    fComposite.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle());

    hookControl(fComposite); // hook help & dispose listener

    fComposite.setLayout(new ContentMergeViewerLayout());

    int style = SWT.SHADOW_OUT;
    fAncestorLabel = new CLabel(fComposite, style | Window.getDefaultOrientation());

    fLeftLabel = new CLabel(fComposite, style | Window.getDefaultOrientation());
    new Resizer(fLeftLabel, VERTICAL);

    fDirectionLabel = new CLabel(fComposite, style);
    fDirectionLabel.setAlignment(SWT.CENTER);
    new Resizer(fDirectionLabel, HORIZONTAL | VERTICAL);

    fRightLabel = new CLabel(fComposite, style | Window.getDefaultOrientation());
    new Resizer(fRightLabel, VERTICAL);

    if (fCenter == null || fCenter.isDisposed()) fCenter = createCenterControl(fComposite);

    createControls(fComposite);

    fHandlerService =
        CompareHandlerService.createFor(
            getCompareConfiguration().getContainer(), fComposite.getShell());

    initializeToolbars(parent);

    return fComposite;
  }
 @Override
 protected Control createCustomArea(Composite parent) {
   Composite composite = new Composite(parent, SWT.NONE);
   composite.setLayout(new GridLayout());
   buttons = new Button[3];
   for (int i = 0; i < 3; i++) {
     buttons[i] = new Button(composite, SWT.RADIO);
     buttons[i].addSelectionListener(selectionListener);
     buttons[i].setText(
         NLS.bind(
             TeamUIMessages.SelectAncestorDialog_option,
             theResources[i].getFullPath().toPortableString()));
     buttons[i].setFont(parent.getFont());
     // set initial state
     buttons[i].setSelection(i == 0);
   }
   pickAncestor(0);
   return composite;
 }
    public void layout(Composite composite, boolean force) {

      // determine some derived sizes
      int headerHeight = fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
      Rectangle r = composite.getClientArea();

      int centerWidth = getCenterWidth();
      int width1 = (int) ((r.width - centerWidth) * getHorizontalSplitRatio());
      int width2 = r.width - width1 - centerWidth;

      int height1 = 0;
      int height2 = 0;
      if (fIsThreeWay && fAncestorVisible) {
        height1 = (int) ((r.height - (2 * headerHeight)) * fVSplit);
        height2 = r.height - (2 * headerHeight) - height1;
      } else {
        height1 = 0;
        height2 = r.height - headerHeight;
      }

      int y = 0;

      if (fIsThreeWay && fAncestorVisible) {
        fAncestorLabel.setBounds(0, y, r.width, headerHeight);
        fAncestorLabel.setVisible(true);
        y += headerHeight;
        handleResizeAncestor(0, y, r.width, height1);
        y += height1;
      } else {
        fAncestorLabel.setVisible(false);
        handleResizeAncestor(0, 0, 0, 0);
      }

      fLeftLabel.getSize(); // without this resizing would not always work

      if (centerWidth > 3) {
        fLeftLabel.setBounds(0, y, width1 + 1, headerHeight);
        fDirectionLabel.setVisible(true);
        fDirectionLabel.setBounds(width1 + 1, y, centerWidth - 1, headerHeight);
        fRightLabel.setBounds(width1 + centerWidth, y, width2, headerHeight);
      } else {
        fLeftLabel.setBounds(0, y, width1, headerHeight);
        fDirectionLabel.setVisible(false);
        fRightLabel.setBounds(width1, y, r.width - width1, headerHeight);
      }

      y += headerHeight;

      if (fCenter != null && !fCenter.isDisposed())
        fCenter.setBounds(width1, y, centerWidth, height2);

      handleResizeLeftRight(0, y, width1, centerWidth, width2, height2);
    }
  private void internalRefresh(Object input) {

    IMergeViewerContentProvider content = getMergeContentProvider();
    if (content == null) {
      return;
    }
    Object ancestor = content.getAncestorContent(input);
    boolean oldFlag = fIsThreeWay;
    if (Utilities.isHunk(input)) {
      fIsThreeWay = true;
    } else if (input instanceof ICompareInput)
      fIsThreeWay = (((ICompareInput) input).getKind() & Differencer.DIRECTION_MASK) != 0;
    else fIsThreeWay = ancestor != null;

    if (fAncestorItem != null) fAncestorItem.setVisible(fIsThreeWay);

    if (fAncestorVisible && oldFlag != fIsThreeWay) fComposite.layout(true);

    Object left = content.getLeftContent(input);
    Object right = content.getRightContent(input);
    updateContent(ancestor, left, right);

    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=453799
    // Content provider may be disposed after call to updateContent()
    content = getMergeContentProvider();
    if (content == null) {
      return;
    }

    updateHeader();
    ToolBarManager tbm = CompareViewerPane.getToolBarManager(fComposite.getParent());
    if (tbm != null) {
      updateToolItems();
      tbm.update(true);
      tbm.getControl().getParent().layout(true);
    }
  }
  /**
   * This method is called from the <code>Viewer</code> method <code>inputChanged</code> to save any
   * unsaved changes of the old input.
   *
   * <p>The <code>ContentMergeViewer</code> implementation of this method calls <code>
   * saveContent(...)</code>. If confirmation has been turned on with <code>setConfirmSave(true)
   * </code>, a confirmation alert is posted before saving. Clients can override this method and are
   * free to decide whether they want to call the inherited method.
   *
   * @param newInput the new input of this viewer, or <code>null</code> if there is no new input
   * @param oldInput the old input element, or <code>null</code> if there was previously no input
   * @return <code>true</code> if saving was successful, or if the user didn't want to save (by
   *     pressing 'NO' in the confirmation dialog).
   * @since 2.0
   */
  protected boolean doSave(Object newInput, Object oldInput) {

    // before setting the new input we have to save the old
    if (isLeftDirty() || isRightDirty()) {

      if (Utilities.RUNNING_TESTS) {
        if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) {
          flushContent(oldInput, null);
        }
      } else if (fConfirmSave) {
        // post alert
        Shell shell = fComposite.getShell();

        MessageDialog dialog =
            new MessageDialog(
                shell,
                Utilities.getString(getResourceBundle(), "saveDialog.title"), // $NON-NLS-1$
                null, // accept the default window icon
                Utilities.getString(getResourceBundle(), "saveDialog.message"), // $NON-NLS-1$
                MessageDialog.QUESTION,
                new String[] {
                  IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL,
                },
                0); // default
        // button
        // index

        switch (dialog.open()) { // open returns index of pressed button
          case 0:
            flushContent(oldInput, null);
            break;
          case 1:
            setLeftDirty(false);
            setRightDirty(false);
            break;
          case 2:
            throw new ViewerSwitchingCancelled();
        }
      } else flushContent(oldInput, null);
      return true;
    }
    return false;
  }