IDEA-131201 github tasks: allow to specify, whether to load all issues or assigned...
[idea/community.git] / plugins / github / src / org / jetbrains / plugins / github / tasks / GithubRepositoryEditor.java
1 package org.jetbrains.plugins.github.tasks;
2
3 import com.intellij.openapi.progress.ProgressIndicator;
4 import com.intellij.openapi.project.Project;
5 import com.intellij.openapi.util.text.StringUtil;
6 import com.intellij.tasks.config.BaseRepositoryEditor;
7 import com.intellij.ui.DocumentAdapter;
8 import com.intellij.ui.components.JBCheckBox;
9 import com.intellij.ui.components.JBLabel;
10 import com.intellij.ui.components.JBTextField;
11 import com.intellij.util.Consumer;
12 import com.intellij.util.ThrowableConvertor;
13 import com.intellij.util.ui.FormBuilder;
14 import com.intellij.util.ui.GridBag;
15 import org.jetbrains.annotations.NotNull;
16 import org.jetbrains.annotations.Nullable;
17 import org.jetbrains.plugins.github.api.GithubApiUtil;
18 import org.jetbrains.plugins.github.api.GithubConnection;
19 import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
20 import org.jetbrains.plugins.github.util.GithubNotifications;
21 import org.jetbrains.plugins.github.util.GithubUtil;
22
23 import javax.swing.*;
24 import javax.swing.event.DocumentEvent;
25 import javax.swing.event.DocumentListener;
26 import java.awt.*;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.io.IOException;
30
31 /**
32  * @author Dennis.Ushakov
33  */
34 public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepository> {
35   private MyTextField myRepoAuthor;
36   private MyTextField myRepoName;
37   private MyTextField myToken;
38   private JBCheckBox myAssignedIssuesOnly;
39   private JButton myTokenButton;
40   private JBLabel myHostLabel;
41   private JBLabel myRepositoryLabel;
42   private JBLabel myTokenLabel;
43
44   public GithubRepositoryEditor(final Project project, final GithubRepository repository, Consumer<GithubRepository> changeListener) {
45     super(project, repository, changeListener);
46     myUrlLabel.setVisible(false);
47     myUsernameLabel.setVisible(false);
48     myUserNameText.setVisible(false);
49     myPasswordLabel.setVisible(false);
50     myPasswordText.setVisible(false);
51     myUseHttpAuthenticationCheckBox.setVisible(false);
52
53     myRepoAuthor.setText(repository.getRepoAuthor());
54     myRepoName.setText(repository.getRepoName());
55     myToken.setText(repository.getToken());
56     myToken.setText(repository.getToken());
57     myAssignedIssuesOnly.setSelected(repository.isAssignedIssuesOnly());
58
59     DocumentListener buttonUpdater = new DocumentAdapter() {
60       @Override
61       protected void textChanged(DocumentEvent e) {
62         updateTokenButton();
63       }
64     };
65
66     myURLText.getDocument().addDocumentListener(buttonUpdater);
67     myRepoAuthor.getDocument().addDocumentListener(buttonUpdater);
68     myRepoName.getDocument().addDocumentListener(buttonUpdater);
69   }
70
71   @Nullable
72   @Override
73   protected JComponent createCustomPanel() {
74     myHostLabel = new JBLabel("Host:", SwingConstants.RIGHT);
75
76     JPanel myHostPanel = new JPanel(new BorderLayout(5, 0));
77     myHostPanel.add(myURLText, BorderLayout.CENTER);
78     myHostPanel.add(myShareUrlCheckBox, BorderLayout.EAST);
79
80     myRepositoryLabel = new JBLabel("Repository:", SwingConstants.RIGHT);
81     myRepoAuthor = new MyTextField("Repository Owner");
82     myRepoName = new MyTextField("Repository Name");
83     myRepoAuthor.setPreferredSize("SomelongNickname");
84     myRepoName.setPreferredSize("SomelongReponame-with-suffixes");
85
86     JPanel myRepoPanel = new JPanel(new GridBagLayout());
87     GridBag bag = new GridBag().setDefaultWeightX(1).setDefaultFill(GridBagConstraints.HORIZONTAL);
88     myRepoPanel.add(myRepoAuthor, bag.nextLine().next());
89     myRepoPanel.add(new JLabel("/"), bag.next().fillCellNone().insets(0, 5, 0, 5).weightx(0));
90     myRepoPanel.add(myRepoName, bag.next());
91
92     myTokenLabel = new JBLabel("API Token:", SwingConstants.RIGHT);
93     myToken = new MyTextField("OAuth2 token");
94     myTokenButton = new JButton("Create API token");
95     myTokenButton.addActionListener(new ActionListener() {
96       public void actionPerformed(ActionEvent e) {
97         generateToken();
98         doApply();
99       }
100     });
101
102     JPanel myTokenPanel = new JPanel();
103     myTokenPanel.setLayout(new BorderLayout(5, 5));
104     myTokenPanel.add(myToken, BorderLayout.CENTER);
105     myTokenPanel.add(myTokenButton, BorderLayout.EAST);
106
107     myAssignedIssuesOnly = new JBCheckBox("Assigned Issues Only");
108
109     installListener(myRepoAuthor);
110     installListener(myRepoName);
111     installListener(myToken);
112     installListener(myAssignedIssuesOnly);
113
114     return FormBuilder.createFormBuilder()
115       .setAlignLabelOnRight(true)
116       .addLabeledComponent(myHostLabel, myHostPanel)
117       .addLabeledComponent(myRepositoryLabel, myRepoPanel)
118       .addLabeledComponent(myTokenLabel, myTokenPanel)
119       .addComponent(myAssignedIssuesOnly)
120       .getPanel();
121   }
122
123   @Override
124   public void apply() {
125     myRepository.setRepoName(getRepoName());
126     myRepository.setRepoAuthor(getRepoAuthor());
127     myRepository.setToken(getToken());
128     myRepository.setAssignedIssuesOnly(isAssignedIssuesOnly());
129     super.apply();
130   }
131
132   private void generateToken() {
133     try {
134       myToken.setText(
135         GithubUtil.computeValueInModal(myProject, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, String, IOException>() {
136           @NotNull
137           @Override
138           public String convert(ProgressIndicator indicator) throws IOException {
139             return GithubUtil
140               .runTaskWithBasicAuthForHost(myProject, GithubAuthDataHolder.createFromSettings(), indicator, getHost(),
141                                            new ThrowableConvertor<GithubConnection, String, IOException>() {
142                                              @NotNull
143                                              @Override
144                                              public String convert(@NotNull GithubConnection connection) throws IOException {
145                                                return GithubApiUtil
146                                                  .getTasksToken(connection, getRepoAuthor(), getRepoName(), "IntelliJ tasks plugin");
147                                              }
148                                            }
149               );
150           }
151         })
152       );
153     }
154     catch (IOException e) {
155       GithubNotifications.showErrorDialog(myProject, "Can't Get Access Token", e);
156     }
157   }
158
159   @Override
160   public void setAnchor(@Nullable final JComponent anchor) {
161     super.setAnchor(anchor);
162     myHostLabel.setAnchor(anchor);
163     myRepositoryLabel.setAnchor(anchor);
164     myTokenLabel.setAnchor(anchor);
165     myAssignedIssuesOnly.setAnchor(anchor);
166   }
167
168   private void updateTokenButton() {
169     if (StringUtil.isEmptyOrSpaces(getHost()) ||
170         StringUtil.isEmptyOrSpaces(getRepoAuthor()) ||
171         StringUtil.isEmptyOrSpaces(getRepoName())) {
172       myTokenButton.setEnabled(false);
173     }
174     else {
175       myTokenButton.setEnabled(true);
176     }
177   }
178
179   @NotNull
180   private String getHost() {
181     return myURLText.getText().trim();
182   }
183
184   @NotNull
185   private String getRepoAuthor() {
186     return myRepoAuthor.getText().trim();
187   }
188
189   @NotNull
190   private String getRepoName() {
191     return myRepoName.getText().trim();
192   }
193
194   @NotNull
195   private String getToken() {
196     return myToken.getText().trim();
197   }
198
199   private boolean isAssignedIssuesOnly() {
200     return myAssignedIssuesOnly.isSelected();
201   }
202
203   public static class MyTextField extends JBTextField {
204     private int myWidth = -1;
205
206     public MyTextField(@NotNull String hintCaption) {
207       getEmptyText().setText(hintCaption);
208     }
209
210     public void setPreferredSize(@NotNull String sampleSizeString) {
211       myWidth = getFontMetrics(getFont()).stringWidth(sampleSizeString);
212     }
213
214     @Override
215     public Dimension getPreferredSize() {
216       Dimension size = super.getPreferredSize();
217       if (myWidth != -1) {
218         size.width = myWidth;
219       }
220       return size;
221     }
222   }
223 }