1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com.dewire.com>
4 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
5 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
7 * All rights reserved. This program and the accompanying materials
8 * are made available under the terms of the Eclipse Public License v1.0
9 * See LICENSE for the full license text, also available.
10 *******************************************************************************/
11 package org
.spearce
.egit
.ui
.internal
.dialogs
;
13 import java
.io
.IOException
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Collections
;
16 import java
.util
.List
;
18 import org
.eclipse
.jface
.dialogs
.Dialog
;
19 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
20 import org
.eclipse
.jface
.dialogs
.IInputValidator
;
21 import org
.eclipse
.jface
.dialogs
.InputDialog
;
22 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
23 import org
.eclipse
.jface
.layout
.GridDataFactory
;
24 import org
.eclipse
.jface
.layout
.GridLayoutFactory
;
25 import org
.eclipse
.jface
.resource
.JFaceResources
;
26 import org
.eclipse
.jface
.window
.Window
;
27 import org
.eclipse
.osgi
.util
.NLS
;
28 import org
.eclipse
.swt
.SWT
;
29 import org
.eclipse
.swt
.events
.DisposeEvent
;
30 import org
.eclipse
.swt
.events
.DisposeListener
;
31 import org
.eclipse
.swt
.events
.SelectionEvent
;
32 import org
.eclipse
.swt
.events
.SelectionListener
;
33 import org
.eclipse
.swt
.graphics
.Font
;
34 import org
.eclipse
.swt
.graphics
.FontData
;
35 import org
.eclipse
.swt
.layout
.GridLayout
;
36 import org
.eclipse
.swt
.layout
.RowLayout
;
37 import org
.eclipse
.swt
.widgets
.Button
;
38 import org
.eclipse
.swt
.widgets
.Composite
;
39 import org
.eclipse
.swt
.widgets
.Event
;
40 import org
.eclipse
.swt
.widgets
.Group
;
41 import org
.eclipse
.swt
.widgets
.Label
;
42 import org
.eclipse
.swt
.widgets
.Listener
;
43 import org
.eclipse
.swt
.widgets
.Shell
;
44 import org
.eclipse
.swt
.widgets
.Tree
;
45 import org
.eclipse
.swt
.widgets
.TreeItem
;
46 import org
.spearce
.egit
.core
.op
.ResetOperation
.ResetType
;
47 import org
.spearce
.egit
.ui
.Activator
;
48 import org
.spearce
.egit
.ui
.UIText
;
49 import org
.spearce
.jgit
.lib
.Constants
;
50 import org
.spearce
.jgit
.lib
.ObjectId
;
51 import org
.spearce
.jgit
.lib
.RefUpdate
;
52 import org
.spearce
.jgit
.lib
.Repository
;
55 * The branch and reset selection dialog
58 public class BranchSelectionDialog
extends Dialog
{
59 private final Repository repo
;
61 private boolean showResetType
= true;
64 * Construct a dialog to select a branch to reset to or check out
68 public BranchSelectionDialog(Shell parentShell
, Repository repo
) {
74 * Pre-set whether or present a reset or checkout dialog
77 public void setShowResetType(boolean show
) {
78 this.showResetType
= show
;
81 private Composite parent
;
83 private Tree branchTree
;
86 protected Composite
createDialogArea(Composite base
) {
87 parent
= (Composite
) super.createDialogArea(base
);
88 parent
.setLayout(GridLayoutFactory
.swtDefaults().create());
89 new Label(parent
, SWT
.NONE
).setText(UIText
.BranchSelectionDialog_Refs
);
90 branchTree
= new Tree(parent
, SWT
.BORDER
);
91 branchTree
.setLayoutData(GridDataFactory
.fillDefaults().grab(true,true).hint(500, 300).create());
97 String rawTitle
= showResetType ? UIText
.BranchSelectionDialog_TitleReset
98 : UIText
.BranchSelectionDialog_TitleCheckout
;
100 NLS
.bind(rawTitle
, new Object
[] { repo
.getDirectory() }));
103 fillTreeWithBranches(null);
104 } catch (IOException e
) {
105 Activator
.logError(UIText
.BranchSelectionDialog_ErrorCouldNotRefresh
, e
);
111 private void buildResetGroup() {
112 Group g
= new Group(parent
, SWT
.NONE
);
113 g
.setText(UIText
.BranchSelectionDialog_ResetType
);
114 g
.setLayoutData(GridDataFactory
.swtDefaults().align(SWT
.CENTER
, SWT
.CENTER
).create());
115 g
.setLayout(new RowLayout(SWT
.VERTICAL
));
117 Button soft
= new Button(g
, SWT
.RADIO
);
118 soft
.setText(UIText
.BranchSelectionDialog_ResetTypeSoft
);
119 soft
.addListener(SWT
.Selection
, new Listener() {
120 public void handleEvent(Event event
) {
121 resetType
= ResetType
.SOFT
;
125 Button medium
= new Button(g
, SWT
.RADIO
);
126 medium
.setSelection(true);
127 medium
.setText(UIText
.BranchSelectionDialog_ResetTypeMixed
);
128 medium
.addListener(SWT
.Selection
, new Listener() {
129 public void handleEvent(Event event
) {
130 resetType
= ResetType
.MIXED
;
134 Button hard
= new Button(g
, SWT
.RADIO
);
135 hard
.setText(UIText
.BranchSelectionDialog_ResetTypeHard
);
136 hard
.addListener(SWT
.Selection
, new Listener() {
137 public void handleEvent(Event event
) {
138 resetType
= ResetType
.HARD
;
143 private void fillTreeWithBranches(String select
) throws IOException
{
144 String branch
= repo
.getFullBranch();
145 List
<String
> branches
= new ArrayList
<String
>(repo
.getAllRefs()
147 Collections
.sort(branches
);
149 TreeItem curItem
= null;
150 TreeItem curSubItem
= null;
151 String curPrefix
= null;
152 String curSubPrefix
= null;
153 TreeItem itemToSelect
= null;
155 for (String ref
: branches
) {
156 String shortName
= ref
;
157 if (ref
.startsWith("refs/heads/")) {
158 shortName
= ref
.substring(11);
159 if (!"refs/heads/".equals(curPrefix
)) {
160 curPrefix
= "refs/heads/";
163 curItem
= new TreeItem(branchTree
, SWT
.NONE
);
164 curItem
.setText(UIText
.BranchSelectionDialog_LocalBranches
);
166 } else if (ref
.startsWith("refs/remotes/")) {
167 shortName
= ref
.substring(13);
168 if (!"refs/remotes/".equals(curPrefix
)) {
169 curPrefix
= "refs/remotes/";
170 curItem
= new TreeItem(branchTree
, SWT
.NONE
);
171 curItem
.setText(UIText
.BranchSelectionDialog_RemoteBranches
);
176 int slashPos
= shortName
.indexOf("/");
178 String remoteName
= shortName
.substring(0, slashPos
);
179 shortName
= shortName
.substring(slashPos
+1);
180 if (!remoteName
.equals(curSubPrefix
)) {
181 curSubItem
= new TreeItem(curItem
, SWT
.NONE
);
182 curSubItem
.setText(remoteName
);
183 curSubPrefix
= remoteName
;
189 } else if (ref
.startsWith("refs/tags/")) {
190 shortName
= ref
.substring(10);
191 if (!"refs/tags/".equals(curPrefix
)) {
192 curPrefix
= "refs/tags/";
195 curItem
= new TreeItem(branchTree
, SWT
.NONE
);
196 curItem
.setText(UIText
.BranchSelectionDialog_Tags
);
201 item
= new TreeItem(branchTree
, SWT
.NONE
);
202 else if (curSubItem
== null)
203 item
= new TreeItem(curItem
, SWT
.NONE
);
204 else item
= new TreeItem(curSubItem
, SWT
.NONE
);
206 if (ref
.equals(branch
)) {
207 item
.setText(shortName
+ UIText
.BranchSelectionDialog_BranchSuffix_Current
);
208 FontData fd
= item
.getFont().getFontData()[0];
209 fd
.setStyle(fd
.getStyle() | SWT
.BOLD
);
210 final Font f
= new Font(getShell().getDisplay(), fd
);
212 item
.addDisposeListener(new DisposeListener() {
213 public void widgetDisposed(DisposeEvent e
) {
217 branchTree
.showItem(item
);
219 else item
.setText(shortName
);
220 if (ref
.equals(select
))
222 branchTree
.setLinesVisible(true);
224 if (itemToSelect
!= null) {
225 branchTree
.select(itemToSelect
);
226 branchTree
.showItem(itemToSelect
);
230 private String refName
= null;
233 * @return Selected ref
235 public String
getRefName() {
239 private ResetType resetType
= ResetType
.MIXED
;
242 * @return Type of Reset
244 public ResetType
getResetType() {
249 protected void okPressed() {
251 if (refName
== null) {
252 MessageDialog
.openWarning(getShell(),
253 UIText
.BranchSelectionDialog_NoBranchSeletectTitle
,
254 UIText
.BranchSelectionDialog_NoBranchSeletectMessage
);
259 if (resetType
== ResetType
.HARD
) {
260 if (!MessageDialog
.openQuestion(getShell(),
261 UIText
.BranchSelectionDialog_ReallyResetTitle
,
262 UIText
.BranchSelectionDialog_ReallyResetMessage
)) {
271 private void refNameFromDialog() {
272 TreeItem
[] selection
= branchTree
.getSelection();
274 if (selection
!= null && selection
.length
> 0) {
275 TreeItem item
= selection
[0];
276 refName
= (String
) item
.getData();
281 protected void createButtonsForButtonBar(Composite parent
) {
282 if (!showResetType
) {
283 Button newButton
= new Button(parent
, SWT
.PUSH
);
284 newButton
.setFont(JFaceResources
.getDialogFont());
285 newButton
.setText(UIText
.BranchSelectionDialog_NewBranch
);
286 ((GridLayout
)parent
.getLayout()).numColumns
++;
287 newButton
.addSelectionListener(new SelectionListener() {
289 public void widgetSelected(SelectionEvent e
) {
290 // check what ref name the user selected, if any.
293 InputDialog labelDialog
= new InputDialog(
295 UIText
.BranchSelectionDialog_QuestionNewBranchTitle
,
296 UIText
.BranchSelectionDialog_QuestionNewBranchMessage
,
297 null, new IInputValidator() {
298 public String
isValid(String newText
) {
299 String testFor
= Constants
.R_HEADS
+ newText
;
301 if (repo
.resolve(testFor
) != null)
302 return UIText
.BranchSelectionDialog_ErrorAlreadyExists
;
303 } catch (IOException e1
) {
304 Activator
.logError(NLS
.bind(
305 UIText
.BranchSelectionDialog_ErrorCouldNotResolve
, testFor
), e1
);
307 if (!Repository
.isValidRefName(testFor
))
308 return UIText
.BranchSelectionDialog_ErrorInvalidRefName
;
312 labelDialog
.setBlockOnOpen(true);
313 if (labelDialog
.open() == Window
.OK
) {
314 String newRefName
= Constants
.R_HEADS
+ labelDialog
.getValue();
317 updateRef
= repo
.updateRef(newRefName
);
320 startAt
= repo
.resolve(Constants
.HEAD
);
322 startAt
= repo
.resolve(refName
);
323 updateRef
.setNewObjectId(startAt
);
325 } catch (IOException e1
) {
326 Activator
.logError(NLS
.bind(
327 UIText
.BranchSelectionDialog_ErrorCouldNotCreateNewRef
,
331 branchTree
.removeAll();
332 fillTreeWithBranches(newRefName
);
333 } catch (IOException e1
) {
335 UIText
.BranchSelectionDialog_ErrorCouldNotRefreshBranchList
,
341 public void widgetDefaultSelected(SelectionEvent e
) {
346 createButton(parent
, IDialogConstants
.OK_ID
,
347 showResetType ? UIText
.BranchSelectionDialog_OkReset
348 : UIText
.BranchSelectionDialog_OkCheckout
, true);
349 createButton(parent
, IDialogConstants
.CANCEL_ID
, IDialogConstants
.CANCEL_LABEL
, false);
353 protected int getShellStyle() {
354 return super.getShellStyle() | SWT
.RESIZE
;