/******************************************************************************* * Copyright (c) 2013 Robin Stocker <robin@nibor.org> and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.egit.ui.internal.push; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.egit.ui.internal.CommonUtils; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.egit.ui.internal.components.CachedCheckboxTreeViewer; import org.eclipse.egit.ui.internal.components.FilteredCheckboxTree; import org.eclipse.egit.ui.internal.components.RemoteSelectionCombo; import org.eclipse.egit.ui.internal.components.RemoteSelectionCombo.SelectionType; import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider; import org.eclipse.egit.ui.internal.repository.RepositoriesViewStyledCellLabelProvider; import org.eclipse.egit.ui.internal.repository.tree.TagNode; import org.eclipse.egit.ui.internal.repository.tree.TagsNode; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.LayoutConstants; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; /** * Tag to select a remote and one or more tags to push. */ public class PushTagsPage extends WizardPage { private final Repository repository; private final Set<String> tagRefNamesToSelect = new HashSet<>(); private RemoteConfig selectedRemoteConfig = null; private List<TagNode> selectedTags = new ArrayList<>(); private boolean forceUpdateSelected = false; private Label tagsLabel; /** * @param repository * @param tagNamesToSelect */ public PushTagsPage(Repository repository, Collection<String> tagNamesToSelect) { super(UIText.PushTagsPage_PageName); setTitle(UIText.PushTagsPage_PageTitle); setMessage(UIText.PushTagsPage_PageMessage); this.repository = repository; for (String tagName : tagNamesToSelect) { if (tagName.startsWith(Constants.R_TAGS)) tagRefNamesToSelect.add(tagName); else tagRefNamesToSelect.add(Constants.R_TAGS + tagName); } } @Override public void createControl(Composite parent) { Composite main = new Composite(parent, SWT.NONE); main.setLayout(GridLayoutFactory.swtDefaults() .spacing(LayoutConstants.getSpacing()).numColumns(2).create()); Label remoteLabel = new Label(main, SWT.NONE); remoteLabel.setText(UIText.PushTagsPage_RemoteLabel); RemoteSelectionCombo remoteSelectionCombo = new RemoteSelectionCombo( main, SWT.NONE, SelectionType.PUSH); remoteSelectionCombo.setLayoutData(GridDataFactory.fillDefaults() .grab(true, false).create()); selectedRemoteConfig = remoteSelectionCombo .setItems(getRemoteConfigs()); remoteSelectionCombo .addRemoteSelectionListener(new RemoteSelectionCombo.IRemoteSelectionListener() { @Override public void remoteSelected(RemoteConfig remoteConfig) { selectedRemoteConfig = remoteConfig; } }); tagsLabel = new Label(main, SWT.NONE); tagsLabel.setText(UIText.PushTagsPage_TagsLabelNoneSelected); tagsLabel.setLayoutData(GridDataFactory.fillDefaults() .grab(true, false).span(2, 1).create()); FilteredCheckboxTree tree = new FilteredCheckboxTree(main, null, SWT.BORDER); tree.setLayoutData(GridDataFactory.fillDefaults().grab(true, true) .span(2, 1).hint(400, 300).create()); final Button forceUpdateButton = new Button(main, SWT.CHECK); forceUpdateButton .setText(UIText.PushTagsPage_ForceUpdateButton); forceUpdateButton.setSelection(false); forceUpdateButton.setLayoutData(GridDataFactory.fillDefaults() .grab(true, false).span(2, 1).create()); forceUpdateButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { forceUpdateSelected = forceUpdateButton.getSelection(); } }); final CachedCheckboxTreeViewer treeViewer = tree .getCheckboxTreeViewer(); TagsNode tagsNode = new TagsNode(null, repository); ContentProvider contentProvider = new ContentProvider(tagsNode); treeViewer.setContentProvider(contentProvider); treeViewer .setLabelProvider(new RepositoriesViewStyledCellLabelProvider()); treeViewer.setComparator(new ViewerComparator( CommonUtils.STRING_ASCENDING_COMPARATOR)); treeViewer.setInput(tagsNode); final Object[] tagNodes = contentProvider.getElements(tagsNode); initiallySelectTags(tagNodes, treeViewer); treeViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { setSelectedTags(treeViewer.getCheckedElements()); } }); setControl(main); } @Override public boolean isPageComplete() { return selectedRemoteConfig != null && !selectedTags.isEmpty(); } RemoteConfig getSelectedRemoteConfig() { return selectedRemoteConfig; } List<TagNode> getSelectedTags() { return selectedTags; } boolean isForceUpdateSelected() { return forceUpdateSelected; } private void initiallySelectTags(Object[] tagNodes, CheckboxTreeViewer viewer) { List<TagNode> checkedTags = new ArrayList<>(); for (Object node : tagNodes) { if (node instanceof TagNode) { TagNode tagNode = (TagNode) node; Ref ref = tagNode.getObject(); if (tagRefNamesToSelect.contains(ref.getName())) checkedTags.add(tagNode); } } TagNode[] checkedTagsArray = checkedTags .toArray(new TagNode[checkedTags.size()]); viewer.setCheckedElements(checkedTagsArray); if (checkedTagsArray.length > 0) { // Reveal tags (just using reveal does not work on some platforms) viewer.setSelection(new StructuredSelection(checkedTagsArray), true); // Clear selection, we don't want to highlight the rows that much viewer.setSelection(StructuredSelection.EMPTY); } setSelectedTags(checkedTagsArray); } private void setSelectedTags(Object[] tags) { selectedTags.clear(); for (Object tag : tags) { if (tag instanceof TagNode) selectedTags.add((TagNode) tag); } int number = selectedTags.size(); if (number == 0) tagsLabel.setText(UIText.PushTagsPage_TagsLabelNoneSelected); else tagsLabel.setText(MessageFormat.format(UIText.PushTagsPage_TagsLabelSelected, Integer.valueOf(selectedTags.size()))); setPageComplete(isPageComplete()); } private List<RemoteConfig> getRemoteConfigs() { try { return RemoteConfig.getAllRemoteConfigs(repository.getConfig()); } catch (URISyntaxException e) { throw new RuntimeException(e); } } private static class ContentProvider extends RepositoriesViewContentProvider { private final Object[] children; private ContentProvider(TagsNode tagsNode) { this.children = getChildren(tagsNode); } @Override public Object[] getElements(Object inputElement) { return children; } } }