Java tutorial
/* * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.community.intellij.plugins.communitycase.ui; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CheckboxTree; import com.intellij.ui.CheckedTreeNode; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Icons; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import org.community.intellij.plugins.communitycase.Branch; import org.community.intellij.plugins.communitycase.Tag; import org.community.intellij.plugins.communitycase.commands.Command; import org.community.intellij.plugins.communitycase.commands.HandlerUtil; import org.community.intellij.plugins.communitycase.commands.SimpleHandler; import org.community.intellij.plugins.communitycase.commands.StringScanner; import org.community.intellij.plugins.communitycase.i18n.Bundle; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashSet; import java.util.SortedSet; import java.util.TreeSet; /** * This dialog allows adding selected tag and branches are references. */ public class RefspecAddRefsDialog extends DialogWrapper { /** * Get references button */ private JButton myGetRefsButton; /** * If selected, the branches are fetched by {@link #myGetRefsButton} */ private JCheckBox myIncludeBranchesCheckBox; /** * If selected, the tags are fetched by {@link #myGetRefsButton} */ private JCheckBox myIncludeTagsCheckBox; /** * The selector for tags and branches */ private CheckboxTree myReferenceChooser; /** * The root panel of the dialog */ private JPanel myPanel; /** * The context project */ private final Project myProject; /** * Root of the tree */ private CheckedTreeNode myTreeRoot; /** * The root of the repository */ private final VirtualFile myRoot; /** * The name of the remote */ private final String myRemote; /** * The set of tags */ private final SortedSet<String> myTags; /** * The set of branches */ private final SortedSet<String> myBranches; /** * The logger for the class */ private static final Logger log = Logger.getInstance("#" + RefspecAddRefsDialog.class.getName()); /** * A constructor * * @param project the project * @param root the repository root * @param remote the remote name or url of remote repository * @param tags the set of tags (might be modified if update button is pressed) * @param branches the set of branches (might be modified if update button is pressed) */ protected RefspecAddRefsDialog(@NotNull Project project, @NotNull VirtualFile root, @NotNull String remote, @NotNull SortedSet<String> tags, @NotNull SortedSet<String> branches) { super(project, true); setTitle(Bundle.getString("addrefspec.title")); setOKButtonText(Bundle.getString("addrefspec.button")); myProject = project; myRoot = root; myRemote = remote; myTags = tags; myBranches = branches; updateTree(); setupGetReferences(); init(); setOKActionEnabled(false); } /** * Set up action listener for {@link #myGetRefsButton} */ private void setupGetReferences() { // setup enabled state final ActionListener enabledListener = new ActionListener() { public void actionPerformed(final ActionEvent e) { myGetRefsButton .setEnabled(myIncludeBranchesCheckBox.isSelected() || myIncludeTagsCheckBox.isSelected()); } }; myIncludeBranchesCheckBox.addActionListener(enabledListener); myIncludeTagsCheckBox.addActionListener(enabledListener); // perform update myGetRefsButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { SimpleHandler handler = new SimpleHandler(myProject, myRoot, Command.LS_REMOTE); if (myIncludeBranchesCheckBox.isSelected()) { handler.addParameters("--heads"); myBranches.clear(); } if (myIncludeTagsCheckBox.isSelected()) { handler.addParameters("--tags"); myTags.clear(); } handler.addParameters(myRemote); String result = HandlerUtil.doSynchronously(handler, Bundle.message("addrefspec.getting.references.title", myRemote), handler.printableCommandLine()); if (result != null) { StringScanner s = new StringScanner(result); while (s.hasMoreData()) { s.tabToken(); // skip last commit hash String ref = s.line(); if (ref.startsWith(Branch.REFS_HEADS_PREFIX)) { myBranches.add(ref); } else if (ref.startsWith(Tag.REFS_TAGS_PREFIX)) { myTags.add(ref); } else { log.warn("Unknwon reference type from ls-remote \"" + myRemote + "\" :" + ref); } } } updateTree(); } }); } /** * Update checkbox tree basing on the current state of the tag and branches set. The checkbox state is preserved. New items are created * in unselected state. */ private void updateTree() { // save the previous selection HashSet<String> oldTags = new HashSet<String>(); HashSet<String> oldBranches = new HashSet<String>(); for (Reference ref : myReferenceChooser.getCheckedNodes(Reference.class, null)) { (ref.isTag ? oldTags : oldBranches).add(ref.name); } // clear the tree myTreeRoot.removeAllChildren(); // fill tags and branches addReferences(false, oldBranches, myBranches, Bundle.getString("addrefspec.node.branches")); addReferences(true, oldTags, myTags, Bundle.getString("addrefspec.node.tags")); TreeUtil.expandAll(myReferenceChooser); myReferenceChooser.treeDidChange(); } /** * Add references to the tree along with category node * * @param isTag if true tag nodes are added * @param old the set of old elements (used to select * @param current the current set of elements (after update) * @param name the name of the set */ private void addReferences(final boolean isTag, final HashSet<String> old, final SortedSet<String> current, @Nls final String name) { if (!current.isEmpty()) { final CheckedTreeNode tagsRoot = new CheckedTreeNode(name); for (String t : current) { final CheckedTreeNode node = new CheckedTreeNode(new Reference(isTag, t)); node.setChecked(old.contains(t)); tagsRoot.add(node); } myTreeRoot.add(tagsRoot); } } /** * {@inheritDoc} */ @Override protected String getDimensionServiceKey() { return RefspecAddRefsDialog.class.getName(); } /** * {@inheritDoc} */ protected JComponent createCenterPanel() { return myPanel; } /** * Create UI components that require custom creation: {@link #myReferenceChooser} */ private void createUIComponents() { myTreeRoot = new CheckedTreeNode(""); myReferenceChooser = new CheckboxTree(new CheckboxTree.CheckboxTreeCellRenderer() { public void customizeCellRenderer(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { // Fix GTK background if (UIUtil.isUnderGTKLookAndFeel()) { final Color background = selected ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeTextBackground(); UIUtil.changeBackGround(this, background); } final CheckedTreeNode node = (CheckedTreeNode) value; final Object userObject = node.getUserObject(); String text; SimpleTextAttributes attributes; Icon icon; if (userObject == null) { // invisible root (do nothing) //noinspection HardCodedStringLiteral text = "INVISBLE ROOT"; attributes = SimpleTextAttributes.ERROR_ATTRIBUTES; icon = null; } else if (userObject instanceof String) { // category node (render as bold) text = (String) userObject; attributes = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES; icon = expanded ? Icons.DIRECTORY_OPEN_ICON : Icons.DIRECTORY_CLOSED_ICON; } else { // reference node text = ((Reference) userObject).name; attributes = node.isChecked() ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES; icon = null; } final ColoredTreeCellRenderer textRenderer = getTextRenderer(); if (icon != null) { textRenderer.setIcon(icon); } if (text != null) { textRenderer.append(text, attributes); } } }, myTreeRoot) { @Override protected void onNodeStateChanged(final CheckedTreeNode node) { boolean flag = node.isChecked() || myReferenceChooser.getCheckedNodes(Reference.class, null).length != 0; setOKActionEnabled(flag); super.onNodeStateChanged(node); } }; } /** * Get selected elements * * @param isTag if true tags are returned, heads otherwise * @return a collection of selected reference of the specified type */ public SortedSet<String> getSelected(final boolean isTag) { TreeSet<String> rc = new TreeSet<String>(); final Reference[] checked = myReferenceChooser.getCheckedNodes(Reference.class, new Tree.NodeFilter<Reference>() { public boolean accept(final Reference node) { return node.isTag == isTag; } }); for (Reference r : checked) { rc.add(r.name); } return rc; } /** * {@inheritDoc} */ @Override protected String getHelpId() { return "reference.VersionControl.Fetch.AddReference"; } /** * A remote reference */ static final class Reference { /** * If true, the name represents a tag. if false, the name represents the branch name. */ final boolean isTag; /** * Name of the reference */ final String name; /** * A constructor from fields * * @param tag the value for {@link #isTag} * @param name the value for {@link #name} */ public Reference(final boolean tag, final String name) { isTag = tag; this.name = name; } } }