org.spearce.egit.ui.internal.dialogs.BranchSelectionDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.spearce.egit.ui.internal.dialogs.BranchSelectionDialog.java

Source

/*******************************************************************************
 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
 * Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com.dewire.com>
 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * See LICENSE for the full license text, also available.
 *******************************************************************************/
package org.spearce.egit.ui.internal.dialogs;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.spearce.egit.core.op.ResetOperation.ResetType;
import org.spearce.egit.ui.Activator;
import org.spearce.jgit.lib.Constants;
import org.spearce.jgit.lib.ObjectId;
import org.spearce.jgit.lib.RefUpdate;
import org.spearce.jgit.lib.Repository;

/**
 * The branch and reset selection dialog
 *
 */
public class BranchSelectionDialog extends Dialog {
    private final Repository repo;

    private boolean showResetType = true;

    /**
     * Construct a dialog to select a branch to reset to or check out
     * @param parentShell
     * @param repo
     */
    public BranchSelectionDialog(Shell parentShell, Repository repo) {
        super(parentShell);
        this.repo = repo;
    }

    /**
     * Pre-set whether or present a reset or checkout dialog
     * @param show
     */
    public void setShowResetType(boolean show) {
        this.showResetType = show;
    }

    private Composite parent;

    private Tree branchTree;

    @Override
    protected Composite createDialogArea(Composite base) {
        parent = (Composite) super.createDialogArea(base);
        parent.setLayout(GridLayoutFactory.swtDefaults().create());

        branchTree = new Tree(parent, SWT.NONE);
        branchTree.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).hint(500, 300).create());

        if (showResetType) {
            buildResetGroup();
        }

        try {
            fillTreeWithBranches(null);
        } catch (IOException e) {
            Activator.logError("Could not refresh list of branches", e);
        }

        return parent;
    }

    private void buildResetGroup() {
        Group g = new Group(parent, SWT.NONE);
        g.setText("Reset Type");
        g.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).create());
        g.setLayout(new RowLayout(SWT.VERTICAL));

        Button soft = new Button(g, SWT.RADIO);
        soft.setText("Soft (Index and working directory unmodified)");
        soft.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                resetType = ResetType.SOFT;
            }
        });

        Button medium = new Button(g, SWT.RADIO);
        medium.setSelection(true);
        medium.setText("Mixed (working directory unmodified)");
        medium.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                resetType = ResetType.MIXED;
            }
        });

        Button hard = new Button(g, SWT.RADIO);
        hard.setText("Hard");
        hard.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                resetType = ResetType.HARD;
            }
        });
    }

    private void fillTreeWithBranches(String select) throws IOException {
        String branch = repo.getFullBranch();
        List<String> branches = new ArrayList<String>(repo.getAllRefs().keySet());
        Collections.sort(branches);

        TreeItem curItem = null;
        TreeItem curSubItem = null;
        String curPrefix = null;
        String curSubPrefix = null;

        for (String ref : branches) {
            String shortName = ref;
            if (ref.startsWith("refs/heads/")) {
                shortName = ref.substring(11);
                if (!"refs/heads/".equals(curPrefix)) {
                    curPrefix = "refs/heads/";
                    curSubPrefix = null;
                    curSubItem = null;
                    curItem = new TreeItem(branchTree, SWT.NONE);
                    curItem.setText("Local Branches");
                }
            } else if (ref.startsWith("refs/remotes/")) {
                shortName = ref.substring(13);
                if (!"refs/remotes/".equals(curPrefix)) {
                    curPrefix = "refs/remotes/";
                    curItem = new TreeItem(branchTree, SWT.NONE);
                    curItem.setText("Remote Branches");
                    curSubItem = null;
                    curSubPrefix = null;
                }

                int slashPos = shortName.indexOf("/");
                if (slashPos > -1) {
                    String remoteName = shortName.substring(0, slashPos);
                    shortName = shortName.substring(slashPos + 1);
                    if (!remoteName.equals(curSubPrefix)) {
                        curSubItem = new TreeItem(curItem, SWT.NONE);
                        curSubItem.setText(remoteName);
                        curSubPrefix = remoteName;
                    }
                } else {
                    curSubItem = null;
                    curSubPrefix = null;
                }
            } else if (ref.startsWith("refs/tags/")) {
                shortName = ref.substring(10);
                if (!"refs/tags/".equals(curPrefix)) {
                    curPrefix = "refs/tags/";
                    curSubPrefix = null;
                    curSubItem = null;
                    curItem = new TreeItem(branchTree, SWT.NONE);
                    curItem.setText("Tags");
                }
            }
            TreeItem item;
            if (curItem == null)
                item = new TreeItem(branchTree, SWT.NONE);
            else if (curSubItem == null)
                item = new TreeItem(curItem, SWT.NONE);
            else
                item = new TreeItem(curSubItem, SWT.NONE);
            item.setData(ref);
            if (ref.equals(branch)) {
                item.setText(shortName + " (current)");
                FontData fd = item.getFont().getFontData()[0];
                fd.setStyle(fd.getStyle() | SWT.BOLD);
                final Font f = new Font(getShell().getDisplay(), fd);
                item.setFont(f);
                item.addDisposeListener(new DisposeListener() {
                    public void widgetDisposed(DisposeEvent e) {
                        f.dispose();
                    }
                });
                branchTree.showItem(item);
            } else
                item.setText(shortName);
            if (ref.equals(select))
                branchTree.select(item);
        }
    }

    private String refName = null;

    /**
     * @return Selected ref
     */
    public String getRefName() {
        return refName;
    }

    private ResetType resetType = ResetType.MIXED;

    /**
     * @return Type of Reset
     */
    public ResetType getResetType() {
        return resetType;
    }

    @Override
    protected void okPressed() {
        refNameFromDialog();
        if (refName == null) {
            MessageDialog.openWarning(getShell(), "No branch/tag selected", "You must select a valid ref.");
            return;
        }

        if (showResetType) {
            if (resetType == ResetType.HARD) {
                if (!MessageDialog.openQuestion(getShell(), "Really reset?",
                        "Resetting will overwrite any changes in your working directory.\n\n"
                                + "Do you wish to continue?")) {
                    return;
                }
            }
        }

        super.okPressed();
    }

    private void refNameFromDialog() {
        TreeItem[] selection = branchTree.getSelection();
        refName = null;
        if (selection != null && selection.length > 0) {
            TreeItem item = selection[0];
            refName = (String) item.getData();
        }
    }

    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        if (!showResetType) {
            Button newButton = new Button(parent, SWT.PUSH);
            newButton.setFont(JFaceResources.getDialogFont());
            newButton.setText("New branch");
            ((GridLayout) parent.getLayout()).numColumns++;
            newButton.addSelectionListener(new SelectionListener() {

                public void widgetSelected(SelectionEvent e) {
                    // check what ref name the user selected, if any.
                    refNameFromDialog();

                    InputDialog labelDialog = new InputDialog(getShell(), "New branch",
                            "Enter name of new branch. It will branch from the selected branch. refs/heads/ will be prepended to the name you type",
                            null, new IInputValidator() {
                                public String isValid(String newText) {
                                    String testFor = Constants.R_HEADS + newText;
                                    try {
                                        if (repo.resolve(testFor) != null)
                                            return "Already exists";
                                    } catch (IOException e1) {
                                        Activator.logError(
                                                String.format("Could not attempt to resolve %s", testFor), e1);
                                    }
                                    if (!Repository.isValidRefName(testFor))
                                        return "Invalid ref name";
                                    return null;
                                }
                            });
                    labelDialog.setBlockOnOpen(true);
                    if (labelDialog.open() == Window.OK) {
                        String newRefName = Constants.R_HEADS + labelDialog.getValue();
                        RefUpdate updateRef;
                        try {
                            updateRef = repo.updateRef(newRefName);
                            ObjectId startAt;
                            if (refName == null)
                                startAt = repo.resolve(Constants.HEAD);
                            else
                                startAt = repo.resolve(refName);
                            updateRef.setNewObjectId(startAt);
                            updateRef.update();
                        } catch (IOException e1) {
                            Activator.logError(String.format("Could not create new ref %s", newRefName), e1);
                        }
                        try {
                            branchTree.removeAll();
                            fillTreeWithBranches(newRefName);
                        } catch (IOException e1) {
                            Activator.logError("Could not refresh list of branches", e1);
                        }
                    }
                }

                public void widgetDefaultSelected(SelectionEvent e) {
                    widgetSelected(e);
                }
            });
        }
        createButton(parent, IDialogConstants.OK_ID, showResetType ? "Reset" : "Checkout", true);
        createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
    }

    @Override
    protected int getShellStyle() {
        return super.getShellStyle() | SWT.RESIZE;
    }
}