blob: 1e23aec62fb10cfee22b4f3f7ef8316ba3d5b0c7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.tags;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.team.internal.ccvs.core.CVSStatus;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.ui.*;
/**
* Dialog to prompt the user to choose a tag for a selected resource
*/
public class TagSelectionDialog extends TrayDialog implements IPropertyChangeListener {
private TagSelectionArea tagSelectionArea;
public static final int INCLUDE_HEAD_TAG = TagSourceWorkbenchAdapter.INCLUDE_HEAD_TAG;
public static final int INCLUDE_BASE_TAG = TagSourceWorkbenchAdapter.INCLUDE_BASE_TAG;
public static final int INCLUDE_BRANCHES = TagSourceWorkbenchAdapter.INCLUDE_BRANCHES;
public static final int INCLUDE_VERSIONS = TagSourceWorkbenchAdapter.INCLUDE_VERSIONS;
public static final int INCLUDE_DATES = TagSourceWorkbenchAdapter.INCLUDE_DATES;
public static final int INCLUDE_ALL_TAGS = TagSourceWorkbenchAdapter.INCLUDE_ALL_TAGS;
private Button okButton;
// dialog title, should indicate the action in which the tag selection
// dialog is being shown
private String title;
private boolean recurse = true;
// constants
private static final int SIZING_DIALOG_WIDTH = 90;
private static final int SIZING_DIALOG_HEIGHT = 25;
private CVSTag selection;
private TagSource tagSource;
private String message;
private int includeFlags;
private String helpContext;
private boolean showRecurse;
public static CVSTag getTagToCompareWith(Shell shell, TagSource tagSource, int includeFlags) {
TagSelectionDialog dialog = new TagSelectionDialog(shell, tagSource,
CVSUIMessages.CompareWithTagAction_message,
CVSUIMessages.TagSelectionDialog_Select_a_Tag_1,
includeFlags,
false, /* show recurse*/
IHelpContextIds.COMPARE_TAG_SELECTION_DIALOG);
dialog.setBlockOnOpen(true);
int result = dialog.open();
if (result == Window.CANCEL) {
return null;
}
return dialog.getResult();
}
/**
* Creates a new TagSelectionDialog.
* @param resource The resource to select a version for.
*/
public TagSelectionDialog(Shell parentShell, TagSource tagSource, String title, String message, int includeFlags, final boolean showRecurse, String helpContext) {
super(parentShell);
// Create a tag selection area with a custom recurse option
this.tagSource = tagSource;
this.message = message;
this.includeFlags = includeFlags;
this.helpContext = helpContext;
this.showRecurse = showRecurse;
this.title = title;
setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
}
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText(title);
}
protected Point getInitialSize() {
final Point size= super.getInitialSize();
size.x= convertWidthInCharsToPixels(SIZING_DIALOG_WIDTH);
size.y= convertHeightInCharsToPixels(SIZING_DIALOG_HEIGHT);
return size;
}
/**
* Creates this window's widgetry.
* <p>
* The default implementation of this framework method
* creates this window's shell (by calling <code>createShell</code>),
* its control (by calling <code>createContents</code>),
* and initializes this window's shell bounds
* (by calling <code>initializeBounds</code>).
* This framework method may be overridden; however,
* <code>super.create</code> must be called.
* </p>
*/
public void create() {
super.create();
initialize();
}
/**
* Add buttons to the dialog's button bar.
*
* @param parent the button bar composite
*/
protected void createButtonsForButtonBar(Composite parent) {
// create OK and Cancel buttons by default
okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
okButton.setEnabled(false);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
}
/**
* Creates and returns the contents of the upper part
* of this dialog (above the button bar).
* <p>
* The default implementation of this framework method
* creates and returns a new <code>Composite</code> with
* standard margins and spacing.
* Subclasses should override.
* </p>
*
* @param parent the parent composite to contain the dialog area
* @return the dialog area control
*/
protected Control createDialogArea(Composite parent) {
applyDialogFont(parent);
initializeDialogUnits(parent);
final Composite top = (Composite)super.createDialogArea(parent);
// Delegate most of the dialog to the tag selection area
tagSelectionArea = new TagSelectionArea(getShell(), tagSource, includeFlags, helpContext) {
protected void createCustomArea(Composite parent) {
if(showRecurse) {
final Button recurseCheck = new Button(parent, SWT.CHECK);
recurseCheck.setText(CVSUIMessages.TagSelectionDialog_recurseOption);
recurseCheck.addListener(SWT.Selection, event -> recurse = recurseCheck.getSelection());
recurseCheck.setSelection(true);
}
}
};
if (message != null)
tagSelectionArea.setTagAreaLabel(message);
tagSelectionArea.addPropertyChangeListener(this);
tagSelectionArea.createArea(top);
tagSelectionArea.setRunnableContext(getRunnableContext());
// Create a separator between the tag area and the button area
final Label seperator = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL);
final GridData data = new GridData (GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
seperator.setLayoutData(data);
updateEnablement();
applyDialogFont(parent);
return top;
}
/**
* Utility method that creates a label instance
* and sets the default layout data.
*
* @param parent the parent for the new label
* @param text the text for the new label
* @return the new label
*/
protected Label createLabel(Composite parent, String text) {
Label label = new Label(parent, SWT.LEFT);
label.setText(text);
GridData data = new GridData();
data.horizontalSpan = 1;
data.horizontalAlignment = GridData.FILL;
label.setLayoutData(data);
return label;
}
/**
* Returns the selected tag.
*/
public CVSTag getResult() {
return selection;
}
public boolean getRecursive() {
return recurse;
}
/**
* Initializes the dialog contents.
*/
protected void initialize() {
okButton.setEnabled(false);
if (CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.PREF_AUTO_REFRESH_TAGS_IN_TAG_SELECTION_DIALOG))
tagSelectionArea.refreshTagList();
}
/**
* Updates the dialog enablement.
*/
protected void updateEnablement() {
if(okButton!=null) {
okButton.setEnabled(selection != null);
}
}
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
if (property.equals(TagSelectionArea.SELECTED_TAG)) {
selection = (CVSTag)event.getNewValue();
updateEnablement();
} else if (property.equals(TagSelectionArea.OPEN_SELECTED_TAG)) {
okPressed();
}
}
/**
* Creates a runnable context that allows refreshing the tags in the background.
*
* @since 3.1
*/
private IRunnableContext getRunnableContext() {
return (fork, cancelable, runnable) -> {
final Job refreshJob = new Job(CVSUIMessages.TagSelectionDialog_7) {
protected IStatus run(IProgressMonitor monitor) {
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
try {
setBusy(true);
runnable.run(monitor);
} catch (InvocationTargetException e) {
return new CVSStatus(IStatus.ERROR, CVSUIMessages.TagSelectionDialog_8, e);
} catch (InterruptedException e) {
return new CVSStatus(IStatus.ERROR, CVSUIMessages.TagSelectionDialog_8, e);
} finally {
setBusy(false);
}
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
else
return Status.OK_STATUS;
}
};
refreshJob.setUser(false);
refreshJob.setPriority(Job.DECORATE);
getShell().addDisposeListener(e -> refreshJob.cancel());
refreshJob.schedule();
};
}
private void setBusy(final boolean busy) {
final Shell shell = getShell();
if (shell != null && !shell.isDisposed()) {
shell.getDisplay().asyncExec(() -> {
if (!shell.isDisposed()) {
Cursor cursor = null;
if (busy) {
cursor = shell.getDisplay().getSystemCursor(SWT.CURSOR_APPSTARTING);
}
shell.setCursor(cursor);
}
});
}
}
}