1 /*******************************************************************************
2 * Copyright (C) 2011, 2015 Dariusz Luksza <dariusz@luksza.org> and others.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org
.eclipse
.egit
.ui
.internal
.actions
;
11 import static org
.eclipse
.jgit
.lib
.Constants
.HEAD
;
12 import static org
.eclipse
.jgit
.lib
.Constants
.R_REFS
;
13 import static org
.eclipse
.jgit
.lib
.Constants
.R_TAGS
;
15 import java
.io
.IOException
;
16 import java
.util
.Collections
;
17 import java
.util
.HashSet
;
18 import java
.util
.LinkedList
;
19 import java
.util
.List
;
21 import org
.eclipse
.core
.resources
.IProject
;
22 import org
.eclipse
.core
.resources
.IResource
;
23 import org
.eclipse
.core
.runtime
.IAdaptable
;
24 import org
.eclipse
.egit
.core
.project
.RepositoryMapping
;
25 import org
.eclipse
.egit
.core
.synchronize
.dto
.GitSynchronizeData
;
26 import org
.eclipse
.egit
.ui
.Activator
;
27 import org
.eclipse
.egit
.ui
.internal
.CommonUtils
;
28 import org
.eclipse
.egit
.ui
.internal
.UIIcons
;
29 import org
.eclipse
.egit
.ui
.internal
.UIText
;
30 import org
.eclipse
.egit
.ui
.internal
.synchronize
.GitModelSynchronize
;
31 import org
.eclipse
.egit
.ui
.internal
.synchronize
.GitSynchronizeWizard
;
32 import org
.eclipse
.jface
.action
.ContributionItem
;
33 import org
.eclipse
.jface
.viewers
.ISelection
;
34 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
35 import org
.eclipse
.jface
.wizard
.WizardDialog
;
36 import org
.eclipse
.jgit
.lib
.Constants
;
37 import org
.eclipse
.jgit
.lib
.ObjectIdRef
.PeeledTag
;
38 import org
.eclipse
.jgit
.lib
.Ref
;
39 import org
.eclipse
.jgit
.lib
.RefDatabase
;
40 import org
.eclipse
.jgit
.lib
.Repository
;
41 import org
.eclipse
.jgit
.revwalk
.RevCommit
;
42 import org
.eclipse
.jgit
.revwalk
.RevTag
;
43 import org
.eclipse
.jgit
.revwalk
.RevWalk
;
44 import org
.eclipse
.swt
.SWT
;
45 import org
.eclipse
.swt
.events
.SelectionAdapter
;
46 import org
.eclipse
.swt
.events
.SelectionEvent
;
47 import org
.eclipse
.swt
.graphics
.Image
;
48 import org
.eclipse
.swt
.widgets
.Menu
;
49 import org
.eclipse
.swt
.widgets
.MenuItem
;
50 import org
.eclipse
.ui
.ISelectionService
;
51 import org
.eclipse
.ui
.menus
.IWorkbenchContribution
;
52 import org
.eclipse
.ui
.services
.IServiceLocator
;
55 * Dynamic sub menu under Team > Synchronize
57 public class SynchronizeWithMenu
extends ContributionItem
implements
58 IWorkbenchContribution
{
60 /** the maximum number of refs to show in the sub-menu */
61 private static final int MAX_NUM_MENU_ENTRIES
= 20;
63 private final Image tagImage
;
65 private final Image branchImage
;
67 private ISelectionService srv
;
72 public SynchronizeWithMenu() {
79 public SynchronizeWithMenu(String id
) {
82 tagImage
= UIIcons
.TAG
.createImage();
83 branchImage
= UIIcons
.BRANCH
.createImage();
87 public void fill(final Menu menu
, int index
) {
90 final IResource selectedResource
= getSelection();
91 if (selectedResource
== null || selectedResource
.isLinked(IResource
.CHECK_ANCESTORS
))
94 RepositoryMapping mapping
= RepositoryMapping
95 .getMapping(selectedResource
.getProject());
99 final Repository repo
= mapping
.getRepository();
103 List
<Ref
> refs
= new LinkedList
<Ref
>();
104 RefDatabase refDatabase
= repo
.getRefDatabase();
106 refs
.addAll(refDatabase
.getAdditionalRefs());
107 } catch (IOException e
) {
111 refs
.addAll(refDatabase
.getRefs(RefDatabase
.ALL
).values());
112 } catch (IOException e
) {
115 Collections
.sort(refs
, CommonUtils
.REF_ASCENDING_COMPARATOR
);
116 String currentBranch
;
118 currentBranch
= repo
.getFullBranch();
119 } catch (IOException e
) {
120 currentBranch
= ""; //$NON-NLS-1$
124 String oldName
= null;
125 int refsLength
= R_REFS
.length();
126 int tagsLength
= R_TAGS
.substring(refsLength
).length();
127 for (Ref ref
: refs
) {
128 final String name
= ref
.getName();
129 if (name
.equals(Constants
.HEAD
) || name
.equals(currentBranch
) || excludeTag(ref
, repo
))
131 if (name
.startsWith(R_REFS
) && oldName
!= null
132 && !oldName
.regionMatches(refsLength
, name
, refsLength
,
134 new MenuItem(menu
, SWT
.SEPARATOR
);
136 MenuItem item
= new MenuItem(menu
, SWT
.PUSH
);
138 if (name
.startsWith(Constants
.R_TAGS
))
139 item
.setImage(tagImage
);
140 else if (name
.startsWith(Constants
.R_HEADS
) || name
.startsWith(Constants
.R_REMOTES
))
141 item
.setImage(branchImage
);
143 item
.addSelectionListener(new SelectionAdapter() {
145 public void widgetSelected(SelectionEvent event
) {
146 GitSynchronizeData data
;
148 data
= new GitSynchronizeData(repo
, HEAD
, name
, true);
149 if (!(selectedResource
instanceof IProject
)) {
150 HashSet
<IResource
> resources
= new HashSet
<IResource
>();
151 resources
.add(selectedResource
);
152 data
.setIncludedResources(resources
);
155 GitModelSynchronize
.launch(data
, new IResource
[] { selectedResource
});
156 } catch (IOException e
) {
157 Activator
.logError(e
.getMessage(), e
);
162 if (++count
== MAX_NUM_MENU_ENTRIES
)
168 new MenuItem(menu
, SWT
.SEPARATOR
);
170 MenuItem custom
= new MenuItem(menu
, SWT
.PUSH
);
171 custom
.setText(UIText
.SynchronizeWithMenu_custom
);
172 custom
.addSelectionListener(new SelectionAdapter() {
174 public void widgetSelected(SelectionEvent e
) {
175 GitSynchronizeWizard gitWizard
= new GitSynchronizeWizard();
176 WizardDialog wizard
= new WizardDialog(menu
.getShell(),
185 public void initialize(IServiceLocator serviceLocator
) {
186 srv
= CommonUtils
.getService(serviceLocator
, ISelectionService
.class);
190 public boolean isDynamic() {
194 public void dispose() {
196 branchImage
.dispose();
199 private IResource
getSelection() {
200 ISelection sel
= srv
.getSelection();
202 if (!(sel
instanceof IStructuredSelection
))
205 Object selected
= ((IStructuredSelection
) sel
).getFirstElement();
206 if (selected
instanceof IAdaptable
)
207 return CommonUtils
.getAdapter(((IAdaptable
) selected
), IResource
.class);
209 if (selected
instanceof IResource
)
210 return (IResource
) selected
;
215 private boolean excludeTag(Ref ref
, Repository repo
) {
216 if (ref
instanceof PeeledTag
) {
217 RevWalk rw
= new RevWalk(repo
);
219 RevTag tag
= rw
.parseTag(ref
.getObjectId());
221 return !(rw
.parseAny(tag
.getObject()) instanceof RevCommit
);
222 } catch (IOException e
) {
223 Activator
.logError(e
.getMessage(), e
);