Package org.sylfra.idea.plugins.revu.ui.forms.issue

Source Code of org.sylfra.idea.plugins.revu.ui.forms.issue.IssueMainForm$ReviewComboBoxModel

package org.sylfra.idea.plugins.revu.ui.forms.issue;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.ListCellRendererWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.sylfra.idea.plugins.revu.RevuBundle;
import org.sylfra.idea.plugins.revu.RevuIconProvider;
import org.sylfra.idea.plugins.revu.business.IReviewListener;
import org.sylfra.idea.plugins.revu.business.ReviewManager;
import org.sylfra.idea.plugins.revu.model.*;
import org.sylfra.idea.plugins.revu.ui.editor.RevuEditorHandler;
import org.sylfra.idea.plugins.revu.ui.multichooser.MultiChooserPanel;
import org.sylfra.idea.plugins.revu.ui.multichooser.UniqueNameMultiChooserItem;
import org.sylfra.idea.plugins.revu.utils.RevuUtils;
import org.sylfra.idea.plugins.revu.utils.RevuVfsUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

/**
* @author <a href="mailto:syllant@gmail.com">Sylvain FRANCOIS</a>
* @version $Id$
*/
public class IssueMainForm extends AbstractIssueForm
{
  private final boolean createMode;
  private final boolean inDialog;
  private MultiChooserPanel<IssueTag, UniqueNameMultiChooserItem<IssueTag>> tagsMultiChooserPanel;
  private JPanel contentPane;
  private JTextArea taDesc;
  private ComboBox cbPriority;
  private JTextArea taSummary;
  private JTextField tfLocation;
  private ComboBox cbReview;
  private JRadioButton rbLocationFile;
  private JRadioButton rbLocationGlobal;
  private JRadioButton rbLocationLineRange;
  private JLabel lbSync;
  private JLabel lbTags;
  private JLabel lbReview;
  private JPanel pnReview;
  private ButtonGroup bgLocation;

  public IssueMainForm(@NotNull Project project, boolean createMode, boolean inDialog)
  {
    super(project);
    this.createMode = createMode;
    this.inDialog = inDialog;
    configureUI();
  }

  private void createUIComponents()
  {
    lbTags = new JLabel();
    tagsMultiChooserPanel = new MultiChooserPanel<IssueTag, UniqueNameMultiChooserItem<IssueTag>>(project, lbTags,
      RevuBundle.message("issueForm.tagsPopup.title"),
      "TagsChooser" + (inDialog ? "Dialog" : ""), RevuIconProvider.IconRef.TAG)
    {
      protected UniqueNameMultiChooserItem<IssueTag> createMultiChooserItem(@NotNull IssueTag issueTag)
      {
        return new UniqueNameMultiChooserItem<IssueTag>(issueTag);
      }

      @Override
      protected List<IssueTag> retrieveAllAvailableElements()
      {
        Review review = (createMode) ? (Review) cbReview.getSelectedItem() : currentIssue.getReview();

        return review.getDataReferential().getIssueTags(true);
      }
    };
  }

  private void configureUI()
  {
    RevuUtils.configureTextAreaAsStandardField(taDesc, taSummary);

    tfLocation.setBorder(BorderFactory.createEmptyBorder());

    ((CardLayout) pnReview.getLayout()).show(pnReview, createMode ? "combo" : "label");

    if (createMode)
    {
      cbReview.setModel(new ReviewComboBoxModel(project));
      cbReview.setRenderer(new ListCellRendererWrapper<Review>()
      {
        @Override
        public void customize(JList list, Review review, int index, boolean selected, boolean hasFocus)
        {
          String tooltip;
          if (review == null)
          {
            tooltip = null;
            setText(RevuBundle.message("general.selectComboValue.text"));
          }
          else
          {
            tooltip = review.isExternalizable() ? review.getFile().getPath() : review.getName();
            setText(review.getName());
          }

          if (tooltip != null)
          {
            setToolTipText(tooltip);
          }
       }
      });

      cbReview.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          Object selectedReview = cbReview.getSelectedItem();
          if (selectedReview != null)
          {
            DataReferential referential = ((Review) selectedReview).getDataReferential();

            cbPriority.setModel(new DefaultComboBoxModel(buildComboItemsArray(
              new TreeSet<IssuePriority>(referential.getIssuePrioritiesByName(true).values()), true)));

            tagsMultiChooserPanel.setEnabled(true);
          }
          else
          {
//             "[Select a value]" String is selected
            cbPriority.setModel(new DefaultComboBoxModel(buildComboItemsArray(new ArrayList(0), true)));

            tagsMultiChooserPanel.setEnabled(false);
          }
        }
      });
    }

    cbPriority.setRenderer(new ListCellRendererWrapper<IssuePriority>()
    {
      @Override
      public void customize(JList jList, IssuePriority value, int i, boolean b, boolean b2)
      {
        if (value == null)
        {
          setText(RevuBundle.message(((createMode) && (cbReview.getSelectedItem() == null))
            ? "general.selectReviewBeforeFillingCombo.text" : "general.selectComboValue.text"));
        }
        else
        {
          setText(value.getName());
        }
      }
    });

    ActionListener locationTypeListener = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        Issue.LocationType locationType = (rbLocationGlobal.isSelected())
          ? Issue.LocationType.GLOBAL
          : ((rbLocationFile.isSelected()) ? Issue.LocationType.FILE : Issue.LocationType.LINE_RANGE);
        updateLocation(locationType);
      }
    };
    rbLocationGlobal.addActionListener(locationTypeListener);
    rbLocationFile.addActionListener(locationTypeListener);
    rbLocationLineRange.addActionListener(locationTypeListener);

    lbSync.addMouseListener(new MouseAdapter()
    {
      @Override
      public void mouseClicked(MouseEvent e)
      {
        assert currentIssue != null;

        RevuEditorHandler editorHandler = project.getComponent(RevuEditorHandler.class);
        currentIssue.setHash(editorHandler.buildNewHash(currentIssue));
        currentIssue.getReview().fireIssueUpdated(currentIssue);
      }
    });
  }

  public JComponent getPreferredFocusedComponent()
  {
    return cbReview.getSelectedIndex() == 0 ? cbReview : taSummary;
  }

  @NotNull
  public JPanel getContentPane()
  {
    return contentPane;
  }

  protected void internalUpdateUI(@Nullable Issue data, boolean requestFocus)
  {
    super.internalUpdateUI(data, requestFocus);

    if (createMode)
    {
      ReviewComboBoxModel reviewComboBoxModel = (ReviewComboBoxModel) cbReview.getModel();
      reviewComboBoxModel.updateReviews();

      Review defaultReview;
      if ((data == null) || (data.getReview() == null))
      {
        defaultReview = RevuUtils.getReviewingReview(project);

        // No reviewing review, see if there is only one review
        if (defaultReview == null)
        {
          if (reviewComboBoxModel.getSize() == 2)
          {
            defaultReview = (Review) reviewComboBoxModel.getElementAt(1);
          }
        }
      }
      else
      {
        defaultReview = data.getReview();
      }

      cbReview.setSelectedItem(defaultReview);
    }
    else
    {
      if ((data != null) && (data.getReview() != null))
      {
        cbPriority.setModel(new DefaultComboBoxModel(buildComboItemsArray(
          new TreeSet<IssuePriority>(
            currentIssue.getReview().getDataReferential().getIssuePrioritiesByName(true).values()), true)));
        lbReview.setText(RevuBundle.message("issueForm.main.review.text", data.getReview().getName(),
          RevuUtils.buildReviewStatusLabel(data.getReview().getStatus(), true)));
      }
    }

    taDesc.setText((data == null) ? "" : data.getDesc());
    taSummary.setText((data == null) ? "" : data.getSummary());
    cbPriority.setSelectedItem((data == null) ? null : data.getPriority());
    lbSync.setVisible((data != null) && (!isIssueSynchronized(data)));
    tagsMultiChooserPanel.setSelectedItemDatas((data == null) ? null : data.getTags());
    tagsMultiChooserPanel.setEnabled((!createMode) || (cbReview.getSelectedItem() != null));

    Issue.LocationType locationType = (data == null) ? null : data.getLocationType();
    updateLocation(locationType);
  }

  protected void internalUpdateData(@NotNull Issue data)
  {
    if (createMode)
    {
      data.setReview((Review) cbReview.getSelectedItem());
    }

    data.setDesc(taDesc.getText());
    data.setSummary(taSummary.getText());
    data.setPriority((IssuePriority) cbPriority.getSelectedItem());
    data.setTags(tagsMultiChooserPanel.getSelectedItemDatas());

    // Location
    if (rbLocationGlobal.isSelected())
    {
      data.setFile(null);
      data.setLineStart(-1);
      data.setLineEnd(-1);
    }
    else if (rbLocationFile.isSelected())
    {
      data.setLineStart(-1);
      data.setLineEnd(-1);
    }
  }

  public boolean isModified(@NotNull Issue data)
  {
    if (!checkEquals(taDesc.getText(), data.getDesc()))
    {
      return true;
    }

    if (!checkEquals(taSummary.getText(), data.getSummary()))
    {
      return true;
    }

    if ((createMode) && (!checkEquals(cbReview.getSelectedItem(), data.getReview())))
    {
      return true;
    }

    if (!checkEquals(cbPriority.getSelectedItem(), data.getPriority()))
    {
      return true;
    }

    if (!checkEquals(tagsMultiChooserPanel.getSelectedItemDatas(), data.getTags()))
    {
      return true;
    }

    if ((bgLocation.getSelection() != null)
      && (!checkEquals(bgLocation.getSelection().getActionCommand(), data.getLocationType().toString())))
    {
      return true;
    }

    return false;
  }

  @Override
  protected void internalUpdateWriteAccess(Issue data, @Nullable User user)
  {
    boolean mayReview = (((createMode) || (user != null))
      && ((currentIssue == null) || (currentIssue.getReview() == null)
      || (IssueStatus.CLOSED != currentIssue.getStatus())));
    RevuUtils.setWriteAccess(mayReview, cbPriority, taSummary, taDesc, rbLocationGlobal);

    Issue.LocationType locationType = (currentIssue == null) ? null : currentIssue.getLocationType();
    rbLocationFile.setEnabled(mayReview && !Issue.LocationType.GLOBAL.equals(locationType));
    rbLocationLineRange.setEnabled(mayReview && !Issue.LocationType.GLOBAL.equals(locationType)
      && !Issue.LocationType.FILE.equals(locationType));

    tagsMultiChooserPanel.setEnabled(mayReview && ((!createMode) || (cbReview.getSelectedIndex() > 0)));
  }

  public void internalValidateInput(@Nullable Issue data)
  {
    updateRequiredError(taSummary, "".equals(taSummary.getText().trim()));
    updateRequiredError(cbReview, (createMode && (!(cbReview.getSelectedItem() instanceof Review))));
  }

  private boolean isIssueSynchronized(Issue issue)
  {
    RevuEditorHandler editorHandler = project.getComponent(RevuEditorHandler.class);
    return editorHandler.isSynchronized(issue, true);
  }

  private void updateLocation(@Nullable Issue.LocationType locationType)
  {
    if (locationType == null)
    {
      rbLocationGlobal.setSelected(true);
      tfLocation.setText("");
    }
    else
    {
      String filePath;
      String locationPath;
      switch (locationType)
      {
        case GLOBAL:
          rbLocationGlobal.setSelected(true);
          locationPath = RevuBundle.message("issueForm.main.location.globalPath.text");
          break;

        case FILE:
          rbLocationFile.setSelected(true);
          filePath = RevuVfsUtils.buildRelativePath(project, currentIssue.getFile());
          locationPath = (currentIssue.getVcsRev() == null)
            ? filePath
            : RevuBundle.message("issueForm.main.location.pathWithVcsRev.text", filePath,
            currentIssue.getVcsRev());
          break;

        default:
          rbLocationLineRange.setSelected(true);
          filePath = RevuVfsUtils.buildRelativePath(project, currentIssue.getFile());
          String filePathWithVcsRev = (currentIssue.getVcsRev() == null)
            ? filePath
            : RevuBundle.message("issueForm.main.location.pathWithVcsRev.text", filePath,
            currentIssue.getVcsRev());
          locationPath = RevuBundle.message("issueForm.main.location.range.path.text",
            filePathWithVcsRev, (currentIssue.getLineStart() + 1), (currentIssue.getLineEnd() + 1));
      }

      tfLocation.setText(locationPath);
      tfLocation.setToolTipText(locationPath);
    }
  }

  private static class ReviewComboBoxModel extends AbstractListModel implements IReviewListener, ComboBoxModel
  {
    private final static Comparator<Review> REVIEW_COMPARATOR = new Comparator<Review>()
    {
      /**
       * {@inheritDoc}
       */
      public int compare(Review r1, Review r2)
      {
        return (r1 == null) ? -1 : ((r2 == null) ? 1 : r1.getName().compareTo(r2.getName()));
      }
    };

    private final Project project;
    private final List<Review> reviews;
    private Review selectedReview;

    private ReviewComboBoxModel(@NotNull Project project)
    {
      this.project = project;
      reviews = new ArrayList<Review>(1);
      reviews.add(null);

      ReviewManager reviewManager = project.getComponent(ReviewManager.class);
      reviewManager.addReviewListener(this);
    }

    public int getSize()
    {
      return reviews.size();
    }

    public Object getElementAt(int index)
    {
      return reviews.get(index);
    }

    public void setSelectedItem(Object item)
    {
      if (((selectedReview != null) && !selectedReview.equals(item)) || ((selectedReview == null) && (item != null)))
      {
        selectedReview = (Review) item;
        fireContentsChanged(this, -1, -1);
      }
    }

    public Object getSelectedItem()
    {
      return selectedReview;
    }

    public void updateReviews()
    {
      reviews.clear();
      reviews.add(null);
      reviews.addAll(RevuUtils.getActiveReviewsForCurrentUser(project));
      Collections.sort(reviews, REVIEW_COMPARATOR);
    }

    public void reviewAdded(Review review)
    {
      if (!RevuUtils.isActiveForCurrentUser(review))
      {
        return;
      }

      reviews.add(review);
      Collections.sort(reviews, REVIEW_COMPARATOR);

      int index = reviews.indexOf(review);
      fireIntervalAdded(this, index, index);
    }

    public void reviewChanged(Review review)
    {
      int index = reviews.indexOf(review);
      if (index == -1)
      {
        if (RevuUtils.isActiveForCurrentUser(review))
        {
          reviewAdded(review);
        }
      }
      else
      {
        if (!RevuUtils.isActiveForCurrentUser(review))
        {
          reviewDeleted(review);
        }
        else
        {
          fireContentsChanged(this, index, index);
        }
      }
    }

    public void reviewDeleted(Review review)
    {
      int index = reviews.indexOf(review);
      if (index > -1)
      {
        reviews.remove(review);
        fireIntervalRemoved(this, index, index);
      }
    }
  }
}
TOP

Related Classes of org.sylfra.idea.plugins.revu.ui.forms.issue.IssueMainForm$ReviewComboBoxModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.