2 * Copyright 2000-2008 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package git4idea
.checkout
;
18 import com
.intellij
.openapi
.project
.Project
;
19 import com
.intellij
.openapi
.ui
.DialogWrapper
;
20 import com
.intellij
.openapi
.vcs
.VcsException
;
21 import com
.intellij
.openapi
.vfs
.VirtualFile
;
22 import com
.intellij
.ui
.DocumentAdapter
;
23 import git4idea
.GitBranch
;
24 import git4idea
.GitTag
;
25 import git4idea
.GitVcs
;
26 import git4idea
.commands
.GitHandler
;
27 import git4idea
.commands
.GitLineHandler
;
28 import git4idea
.commands
.GitSimpleHandler
;
29 import git4idea
.config
.GitVcsSettings
;
30 import git4idea
.i18n
.GitBundle
;
31 import git4idea
.ui
.GitReferenceValidator
;
32 import git4idea
.ui
.GitUIUtil
;
33 import git4idea
.validators
.GitBranchNameValidator
;
34 import org
.jetbrains
.annotations
.Nullable
;
37 import javax
.swing
.event
.DocumentEvent
;
38 import java
.awt
.event
.ActionEvent
;
39 import java
.awt
.event
.ActionListener
;
40 import java
.util
.ArrayList
;
41 import java
.util
.Collections
;
42 import java
.util
.HashSet
;
43 import java
.util
.List
;
46 * Checkout dialog. It also allows checking out a new branch.
48 public class GitCheckoutDialog
extends DialogWrapper
{
52 private JPanel myPanel
;
56 private JComboBox myGitRoot
;
58 * Branch/tag to check out
60 private JComboBox myBranchToCkeckout
;
64 private JLabel myCurrentBranch
;
66 * Checkbox that specifies whether tags are included into drop down
68 private JCheckBox myIncludeTagsCheckBox
;
70 * The name of new branch
72 private JTextField myNewBranchName
;
74 * The delete branch before checkout flag
76 private JCheckBox myOverrideCheckBox
;
78 * The create reference log checkbox
80 private JCheckBox myCreateRefLogCheckBox
;
82 * The track branch checkbox
84 private JCheckBox myTrackBranchCheckBox
;
86 * The validator for branch to checkout
88 private final GitReferenceValidator myBranchToCkeckoutValidator
;
92 private JButton myValidateButton
;
96 private final Project myProject
;
98 * The Git setting for the project
100 private final GitVcsSettings mySettings
;
102 * Existing branches for the currently selected root
104 private final HashSet
<String
> existingBranches
= new HashSet
<String
>();
109 * @param project the context project
110 * @param roots the git roots for the project
111 * @param defaultRoot the default root
113 public GitCheckoutDialog(Project project
, List
<VirtualFile
> roots
, VirtualFile defaultRoot
) {
114 super(project
, true);
115 setTitle(GitBundle
.getString("checkout.branch"));
117 mySettings
= GitVcsSettings
.getInstance(myProject
);
118 GitUIUtil
.setupRootChooser(myProject
, roots
, defaultRoot
, myGitRoot
, myCurrentBranch
);
121 setOKButtonText(GitBundle
.getString("checkout.branch"));
122 myBranchToCkeckoutValidator
=
123 new GitReferenceValidator(project
, myGitRoot
, getBranchToCheckoutTextField(), myValidateButton
, new Runnable() {
128 setupNewBranchName();
134 * Validate if ok button should be enabled and set appropriate error
136 private void checkOkButton() {
137 final String sourceRev
= getSourceBranch();
138 if (sourceRev
== null || sourceRev
.length() == 0) {
140 setOKActionEnabled(false);
143 if (myBranchToCkeckoutValidator
.isInvalid()) {
144 setErrorText(GitBundle
.getString("checkout.validation.failed"));
145 setOKActionEnabled(false);
148 final String newBranchName
= myNewBranchName
.getText();
149 if (newBranchName
.length() != 0 && !GitBranchNameValidator
.INSTANCE
.checkInput(newBranchName
)) {
150 setErrorText(GitBundle
.getString("checkout.invalid.new.branch.name"));
151 setOKActionEnabled(false);
154 if (existingBranches
.contains(newBranchName
) && !myOverrideCheckBox
.isSelected()) {
155 setErrorText(GitBundle
.getString("checkout.branch.name.exists"));
156 setOKActionEnabled(false);
160 setOKActionEnabled(true);
164 * Setup {@link #myNewBranchName}
166 private void setupNewBranchName() {
167 myOverrideCheckBox
.addActionListener(new ActionListener() {
168 public void actionPerformed(final ActionEvent e
) {
172 final DocumentAdapter l
= new DocumentAdapter() {
173 protected void textChanged(final DocumentEvent e
) {
175 final String text
= myNewBranchName
.getText();
176 if (text
.length() == 0) {
180 if (GitBranchNameValidator
.INSTANCE
.checkInput(text
)) {
181 if (existingBranches
.contains(text
)) {
182 myOverrideCheckBox
.setEnabled(true);
185 myOverrideCheckBox
.setEnabled(false);
186 myOverrideCheckBox
.setSelected(false);
188 if (existingBranches
.contains(getSourceBranch())) {
189 if (!myTrackBranchCheckBox
.isEnabled()) {
190 myTrackBranchCheckBox
.setSelected(true);
191 myTrackBranchCheckBox
.setEnabled(true);
195 myTrackBranchCheckBox
.setSelected(false);
196 myTrackBranchCheckBox
.setEnabled(false);
198 myCreateRefLogCheckBox
.setEnabled(true);
206 private void disableCheckboxes() {
207 myOverrideCheckBox
.setSelected(false);
208 myOverrideCheckBox
.setEnabled(false);
209 myTrackBranchCheckBox
.setSelected(false);
210 myTrackBranchCheckBox
.setEnabled(false);
211 myCreateRefLogCheckBox
.setSelected(false);
212 myCreateRefLogCheckBox
.setEnabled(false);
215 myNewBranchName
.getDocument().addDocumentListener(l
);
216 final JTextField text
= getBranchToCheckoutTextField();
217 text
.getDocument().addDocumentListener(l
);
221 * @return text field for branch to checkout
223 private JTextField
getBranchToCheckoutTextField() {
224 return (JTextField
)myBranchToCkeckout
.getEditor().getEditorComponent();
228 * @return the branch, tag, or expression to checkout
230 public String
getSourceBranch() {
231 return GitUIUtil
.getTextField(myBranchToCkeckout
).getText();
235 * Setup {@link #myBranchToCkeckout}
237 private void setupBranches() {
238 ActionListener l
= new ActionListener() {
239 public void actionPerformed(final ActionEvent e
) {
241 List
<String
> branchesAndTags
= new ArrayList
<String
>();
243 GitBranch
.listAsStrings(myProject
, gitRoot(), true, true, branchesAndTags
);
244 existingBranches
.clear();
245 existingBranches
.addAll(branchesAndTags
);
246 Collections
.sort(branchesAndTags
);
248 if (myIncludeTagsCheckBox
.isSelected()) {
249 int mark
= branchesAndTags
.size();
250 GitTag
.listAsStrings(myProject
, gitRoot(), branchesAndTags
);
251 Collections
.sort(branchesAndTags
.subList(mark
, branchesAndTags
.size()));
253 myBranchToCkeckout
.removeAllItems();
254 for (String item
: branchesAndTags
) {
255 myBranchToCkeckout
.addItem(item
);
257 myBranchToCkeckout
.setSelectedItem("");
259 catch (VcsException ex
) {
260 GitVcs
.getInstance(myProject
)
261 .showErrors(Collections
.singletonList(ex
), GitBundle
.getString("checkout.retriving.branches.and.tags"));
265 myGitRoot
.addActionListener(l
);
266 l
.actionPerformed(null);
267 myIncludeTagsCheckBox
.addActionListener(l
);
271 * @return a handler that creates branch or null if branch creation is not needed.
274 public GitSimpleHandler
createBranchHandler() {
275 final String branch
= myNewBranchName
.getText();
276 if (branch
.length() == 0) {
279 GitSimpleHandler h
= new GitSimpleHandler(myProject
, gitRoot(), GitHandler
.BRANCH
);
281 if (myTrackBranchCheckBox
.isSelected()) {
282 h
.addParameters("--track");
284 if (myCreateRefLogCheckBox
.isSelected()) {
285 h
.addParameters("-l");
287 if (myOverrideCheckBox
.isSelected()) {
288 h
.addParameters("-f");
290 h
.addParameters(branch
, getSourceBranch());
295 * @return a handler that checkouts branch
297 public GitLineHandler
checkoutHandler() {
298 GitLineHandler h
= new GitLineHandler(myProject
, gitRoot(), GitHandler
.CHECKOUT
);
300 final String newBranch
= myNewBranchName
.getText();
301 if (newBranch
.length() == 0) {
302 h
.addParameters(getSourceBranch());
305 h
.addParameters(newBranch
);
312 * @return a currently selected git root
314 public VirtualFile
gitRoot() {
315 return (VirtualFile
)myGitRoot
.getSelectedItem();
319 * Setup {@link #myIncludeTagsCheckBox}
321 private void setupIncludeTags() {
322 Boolean tagsIncluded
= mySettings
.CHECKOUT_INCLUDE_TAGS
;
323 if (tagsIncluded
== null) {
324 tagsIncluded
= Boolean
.FALSE
;
326 myIncludeTagsCheckBox
.setSelected(tagsIncluded
.booleanValue());
327 myIncludeTagsCheckBox
.addActionListener(new ActionListener() {
328 public void actionPerformed(final ActionEvent e
) {
329 mySettings
.CHECKOUT_INCLUDE_TAGS
= myIncludeTagsCheckBox
.isSelected();
337 protected JComponent
createCenterPanel() {
345 protected String
getDimensionServiceKey() {
346 return getClass().getName();
353 protected String
getHelpId() {
354 return "reference.VersionControl.Git.CheckoutBranch";