void fillCompareWithMenu(ChangeDetail changeDetail, PatchSetDetail patchSetDetail, Menu menu) {
   for (PatchSet patchSet : changeDetail.getPatchSets()) {
     if (patchSet.getPatchSetId() != patchSetDetail.getPatchSet().getPatchSetId()) {
       CompareAction action =
           new CompareAction(changeDetail, patchSet, patchSetDetail.getPatchSet());
       action.fill(menu);
     }
   }
 }
 private int getNumComments(PatchSetDetail patchSetDetail) {
   int numComments = 0;
   for (Patch patch : patchSetDetail.getPatches()) {
     numComments += patch.getCommentCount();
   }
   return numComments;
 }
  private void createSubSection(
      final ChangeDetail changeDetail,
      final PatchSetDetail patchSetDetail,
      final PatchSetPublishDetail publishDetail,
      Section section) {
    int style =
        ExpandableComposite.TWISTIE
            | ExpandableComposite.CLIENT_INDENT
            | ExpandableComposite.LEFT_TEXT_CLIENT_ALIGNMENT;
    if (changeDetail.isCurrentPatchSet(patchSetDetail)) {
      style |= ExpandableComposite.EXPANDED;
    }
    final Section subSection = toolkit.createSection(composite, style);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(subSection);
    subSection.setText(NLS.bind("Patch Set {0}", patchSetDetail.getPatchSet().getId().get()));
    subSection.setTitleBarForeground(toolkit.getColors().getColor(IFormColors.TITLE));

    addTextClient(toolkit, subSection, "", false); // $NON-NLS-1$
    updateTextClient(subSection, patchSetDetail, false);

    if (subSection.isExpanded()) {
      createSubSectionContents(changeDetail, patchSetDetail, publishDetail, subSection);
    }
    subSection.addExpansionListener(
        new ExpansionAdapter() {
          @Override
          public void expansionStateChanged(ExpansionEvent e) {
            if (subSection.getClient() == null) {
              createSubSectionContents(changeDetail, patchSetDetail, publishDetail, subSection);
            }
          }
        });
  }
  @Override
  protected Control createContent(FormToolkit toolkit, Composite parent) {
    this.toolkit = toolkit;

    composite = toolkit.createComposite(parent);
    GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 0, 5).applyTo(composite);

    GerritChange change = GerritUtil.getChange(getTaskData());
    if (change != null) {
      for (PatchSetDetail patchSetDetail : change.getPatchSetDetails()) {
        PatchSet.Id patchSetId = patchSetDetail.getPatchSet().getId();
        PatchSetPublishDetail publishDetail = change.getPublishDetailByPatchSetId().get(patchSetId);
        createSubSection(change.getChangeDetail(), patchSetDetail, publishDetail, getSection());
      }
    }

    return composite;
  }
 protected void doFetch(ChangeDetail changeDetail, PatchSetDetail patchSetDetail) {
   GerritToGitMapping mapping = getRepository(changeDetail);
   if (mapping != null) {
     String refName = patchSetDetail.getPatchSet().getRefName();
     FetchGerritChangeWizard wizard =
         new FetchGerritChangeWizard(mapping.getRepository(), refName);
     WizardDialog wizardDialog = new WizardDialog(getShell(), wizard);
     wizardDialog.setHelpAvailable(false);
     wizardDialog.open();
   }
 }
  public void updateTextClient(
      Section section, final PatchSetDetail patchSetDetail, boolean cachingInProgress) {
    String message;

    String time =
        DateFormat.getDateTimeInstance().format(patchSetDetail.getPatchSet().getCreatedOn());
    int numComments = getNumComments(patchSetDetail);
    if (numComments > 0) {
      message = NLS.bind("{0}, {1} Comments", time, numComments);
    } else {
      message = NLS.bind("{0}", time);
    }

    if (cachingInProgress) {
      message += " [Caching contents...]";
    }

    final Label textClientLabel = (Label) section.getTextClient();
    textClientLabel.setText("  " + message);
    textClientLabel.getParent().layout(true, true);
    // textClientLabel.setVisible(cachingInProgress || !section.isExpanded());
  }
  void createSubSectionContents(
      final ChangeDetail changeDetail,
      final PatchSetDetail patchSetDetail,
      PatchSetPublishDetail publishDetail,
      Section subSection) {
    Composite composite = toolkit.createComposite(subSection);
    GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);
    subSection.setClient(composite);

    Label authorLabel = new Label(composite, SWT.NONE);
    authorLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
    authorLabel.setText("Author");

    Text authorText = new Text(composite, SWT.READ_ONLY);
    authorText.setText(GerritUtil.getUserLabel(patchSetDetail.getInfo().getAuthor()));

    Label committerLabel = new Label(composite, SWT.NONE);
    committerLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
    committerLabel.setText("Committer");

    Text committerText = new Text(composite, SWT.READ_ONLY);
    committerText.setText(GerritUtil.getUserLabel(patchSetDetail.getInfo().getCommitter()));

    Label commitLabel = new Label(composite, SWT.NONE);
    commitLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
    commitLabel.setText("Commit");

    Hyperlink commitLink = new Hyperlink(composite, SWT.READ_ONLY);
    commitLink.setText(patchSetDetail.getPatchSet().getRevision().get());
    commitLink.addHyperlinkListener(
        new HyperlinkAdapter() {
          @Override
          public void linkActivated(HyperlinkEvent event) {
            GerritToGitMapping mapping = getRepository(changeDetail);
            if (mapping != null) {
              final FetchPatchSetJob job =
                  new FetchPatchSetJob(
                      "Opening Commit Viewer",
                      mapping.getRepository(),
                      mapping.getRemote(),
                      patchSetDetail.getPatchSet());
              job.schedule();
              job.addJobChangeListener(
                  new JobChangeAdapter() {
                    @Override
                    public void done(IJobChangeEvent event) {
                      Display.getDefault()
                          .asyncExec(
                              new Runnable() {
                                @Override
                                public void run() {
                                  CommitEditor.openQuiet(job.getCommit());
                                }
                              });
                    }
                  });
            }
          }
        });

    Label refLabel = new Label(composite, SWT.NONE);
    refLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
    refLabel.setText("Ref");

    Text refText = new Text(composite, SWT.READ_ONLY);
    refText.setText(patchSetDetail.getPatchSet().getRefName());

    final TableViewer viewer =
        new TableViewer(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.VIRTUAL);
    GridDataFactory.fillDefaults()
        .span(2, 1)
        .grab(true, true)
        .hint(500, SWT.DEFAULT)
        .applyTo(viewer.getControl());
    viewer.setContentProvider(
        new IStructuredContentProvider() {
          private EContentAdapter modelAdapter;

          public void dispose() {
            // ignore
          }

          public Object[] getElements(Object inputElement) {
            return getReviewItems(inputElement).toArray();
          }

          private List<IReviewItem> getReviewItems(Object inputElement) {
            if (inputElement instanceof IReviewItemSet) {
              return ((IReviewItemSet) inputElement).getItems();
            }
            return Collections.emptyList();
          }

          public void inputChanged(final Viewer viewer, Object oldInput, Object newInput) {
            if (modelAdapter != null) {
              for (IReviewItem item : getReviewItems(oldInput)) {
                ((EObject) item).eAdapters().remove(modelAdapter);
              }
              addedDrafts = 0;
            }

            if (newInput instanceof IReviewItemSet) {
              // monitors any new topics that are added
              modelAdapter =
                  new EContentAdapter() {
                    @Override
                    public void notifyChanged(Notification notification) {
                      super.notifyChanged(notification);
                      if (notification.getFeatureID(IReviewItem.class)
                              == ReviewsPackage.REVIEW_ITEM__TOPICS
                          && notification.getEventType() == Notification.ADD) {
                        viewer.refresh();
                        addedDrafts++;
                      }
                    }
                  };
              for (Object item : getReviewItems(newInput)) {
                ((EObject) item).eAdapters().add(modelAdapter);
              }
            }
          }
        });
    viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(new ReviewItemLabelProvider()));
    viewer.addOpenListener(
        new IOpenListener() {
          public void open(OpenEvent event) {
            IStructuredSelection selection = (IStructuredSelection) event.getSelection();
            IFileItem item = (IFileItem) selection.getFirstElement();
            if (item != null) {
              doOpen((IReviewItemSet) viewer.getInput(), item);
            }
          }
        });

    IReviewItemSet itemSet =
        GerritUtil.createInput(changeDetail, new GerritPatchSetContent(patchSetDetail), cache);
    viewer.setInput(itemSet);

    Composite actionComposite =
        createActions(changeDetail, patchSetDetail, publishDetail, composite);
    GridDataFactory.fillDefaults().span(2, 1).applyTo(actionComposite);

    subSectionExpanded(changeDetail, patchSetDetail, subSection, viewer);
    EditorUtil.addScrollListener(viewer.getTable());

    getTaskEditorPage().reflow();
  }