// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.dataprofiler.core.ui.dialog; import java.util.HashMap; import java.util.Map; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.operations.IUndoableOperation; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.undo.CreateMarkersOperation; import org.eclipse.ui.ide.undo.UpdateMarkersOperation; import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; import org.eclipse.ui.views.markers.internal.MarkerMessages; import org.eclipse.ui.views.markers.internal.Util; /** * * DOC mzhao class global comment. Detailled comment */ @SuppressWarnings("restriction") public class TdDialogMarkerProperties extends TrayDialog { private static final String DIALOG_SETTINGS_SECTION = "DialogMarkerPropertiesDialogSettings"; //$NON-NLS-1$ /** * The marker being shown, or <code>null</code> for a new marker. */ private IMarker marker = null; /** * The resource on which to create a new marker. */ private IResource resource = null; /** * The type of marker to be created. */ private String type = IMarker.MARKER; /** * The initial attributes to use when creating a new marker. */ @SuppressWarnings("unchecked") private Map initialAttributes = null; /** * The text control for the Description field. */ private Text descriptionText; /** * The control for the Creation Time field. */ private Label creationTime; /** * The text control for the Resource field. */ private Text resourceText; /** * The text control for the Folder field. */ private Text folderText; /** * The text control for the Location field. */ private Text locationText; /** * Dirty flag. True if any changes have been made. */ private boolean dirty; private String title; /** * The name used to describe the specific kind of marker. Used when creating an undo command for the dialog, so that * a specific name such as "Undo Create Task" or "Undo Modify Bookmark" can be used. */ private String markerName; /** * Creates the dialog. By default this dialog creates a new marker. To set the resource and initial attributes for * the new marker, use <code>setResource</code> and <code>setInitialAttributes</code>. To show or modify an existing * marker, use <code>setMarker</code>. * * @param parentShell the parent shell */ public TdDialogMarkerProperties(Shell parentShell) { super(parentShell); } /** * Creates the dialog. By default this dialog creates a new marker. To set the resource and initial attributes for * the new marker, use <code>setResource</code> and <code>setInitialAttributes</code>. To show or modify an existing * marker, use <code>setMarker</code>. * * @param parentShell the parent shell * @param title the title of the dialog */ public TdDialogMarkerProperties(Shell parentShell, String title) { super(parentShell); this.title = title; } /** * Creates the dialog. By default this dialog creates a new marker. To set the resource and initial attributes for * the new marker, use <code>setResource</code> and <code>setInitialAttributes</code>. To show or modify an existing * marker, use <code>setMarker</code>. * * @param parentShell the parent shell * @param title the title of the dialog * @param markerName the name used to describe the specific kind of marker shown * * @since 3.3 */ public TdDialogMarkerProperties(Shell parentShell, String title, String markerName) { super(parentShell); this.title = title; this.markerName = markerName; } /** * Sets the marker to show or modify. * <p> * IMPORTANT: Although this class is internal, there are public subclasses that expose this method as API. Changes * in this implementation should be treated as API changes. * * @param marker the marker, or <code>null</code> to create a new marker * * @since 3.3 */ public void setMarker(IMarker marker) { this.marker = marker; if (marker != null) { try { type = marker.getType(); } catch (CoreException e) { e.printStackTrace(); } } } /** * Returns the marker being created or modified. For a new marker, this returns <code>null</code> until the dialog * returns, but is non-null after. * <p> * IMPORTANT: Although this method is protected and the class is internal, there are public subclasses that expose * this method as API. Changes in this implementation should be treated as API changes. * * @return the marker * * @since 3.3 */ protected IMarker getMarker() { return marker; } /** * Sets the resource to use when creating a new task. If not set, the new task is created on the workspace root. * <p> * IMPORTANT: Although this class is internal, there are public subclasses that expose this method as API. Changes * in this implementation should be treated as API changes. * * @param resource the resource */ public void setResource(IResource resource) { this.resource = resource; } /** * Returns the resource to use when creating a new task, or <code>null</code> if none has been set. If not set, the * new task is created on the workspace root. * <p> * IMPORTANT: Although this method is protected and the class is internal, there are public subclasses that expose * this method as API. Changes in this implementation should be treated as API changes. * * @return the resource * * @since 3.3 */ protected IResource getResource() { return resource; } /** * Sets initial attributes to use when creating a new task. If not set, the new task is created with default * attributes. * <p> * IMPORTANT: Although this method is protected and the class is internal, there are public subclasses that expose * this method as API. Changes in this implementation should be treated as API changes. * * @param initialAttributes the initial attributes * * @since 3.3 */ @SuppressWarnings("unchecked") public void setInitialAttributes(Map initialAttributes) { this.initialAttributes = initialAttributes; } /** * Returns the initial attributes to use when creating a new task, or <code>null</code> if not set. If not set, the * new task is created with default attributes. * <p> * IMPORTANT: Although this method is protected and the class is internal, there are public subclasses that expose * this method as API. Changes in this implementation should be treated as API changes. * * @return the initial attributes * * @since 3.3 */ @SuppressWarnings("unchecked") protected Map getInitialAttributes() { if (initialAttributes == null) { initialAttributes = new HashMap(); } return initialAttributes; } /** * Method declared on Window. */ protected void configureShell(Shell newShell) { super.configureShell(newShell); if (title == null) { newShell.setText(MarkerMessages.propertiesDialog_title);//$NON-NLS-1$ } else { newShell.setText(title); } } /** * Method declared on Dialog. */ protected Control createDialogArea(Composite parent) { // initialize resources/properties if (marker != null) { resource = marker.getResource(); try { initialAttributes = marker.getAttributes(); } catch (CoreException e) { e.printStackTrace(); } } else if (resource == null) { resource = ResourcesPlugin.getWorkspace().getRoot(); } Composite comp = (Composite) super.createDialogArea(parent); Composite composite = new Composite(comp, SWT.NULL); GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; composite.setLayout(layout); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); composite.setLayoutData(gridData); initializeDialogUnits(composite); createDescriptionArea(composite); if (marker != null) { createSeperator(composite); createCreationTimeArea(composite); } createAttributesArea(composite); if (resource != null) { createSeperator(composite); createResourceArea(composite); } updateDialogFromMarker(); updateEnablement(); Dialog.applyDialogFont(composite); return composite; } /** * Creates a seperator. */ protected void createSeperator(Composite parent) { Label seperator = new Label(parent, SWT.NULL); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 2; seperator.setLayoutData(gridData); } /** * Method createCreationTimeArea. * * @param parent */ private void createCreationTimeArea(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText(MarkerMessages.propertiesDialog_creationTime_text);//$NON-NLS-1$ creationTime = new Label(parent, SWT.NONE); } /** * Creates the OK and Cancel buttons. */ protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } /** * Creates the area for the Description field. */ private void createDescriptionArea(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText(MarkerMessages.propertiesDialog_description_text);//$NON-NLS-1$ descriptionText = new Text(parent, (SWT.SINGLE | SWT.BORDER)); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.widthHint = convertHorizontalDLUsToPixels(400); descriptionText.setLayoutData(gridData); descriptionText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { markDirty(); } }); } /** * This method is intended to be overridden by subclasses. The attributes area is created between the creation time * area and the resource area. * * @param parent the parent composite */ protected void createAttributesArea(Composite parent) { } /** * Creates the area for the Resource field. */ private void createResourceArea(Composite parent) { Label resourceLabel = new Label(parent, SWT.NONE); resourceLabel.setText(MarkerMessages.propertiesDialog_resource_text);//$NON-NLS-1$ resourceText = new Text(parent, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); resourceText.setLayoutData(gridData); Label folderLabel = new Label(parent, SWT.NONE); folderLabel.setText(MarkerMessages.propertiesDialog_folder_text); folderText = new Text(parent, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); gridData = new GridData(GridData.FILL_HORIZONTAL); folderText.setLayoutData(gridData); Label locationLabel = new Label(parent, SWT.NONE); locationLabel.setText(MarkerMessages.propertiesDialog_location_text); locationText = new Text(parent, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); gridData = new GridData(GridData.FILL_HORIZONTAL); locationText.setLayoutData(gridData); } /** * Updates the dialog from the marker state. */ protected void updateDialogFromMarker() { if (marker == null) { updateDialogForNewMarker(); return; } descriptionText.setText(Util.getProperty(IMarker.MESSAGE, marker)); if (creationTime != null) { creationTime.setText(Util.getCreationTime(marker)); } if (resourceText != null) { resourceText.setText(Util.getResourceName(marker)); } if (folderText != null) { folderText.setText(Util.getContainerName(marker)); } if (locationText != null) { String line = Util.getProperty(IMarker.LINE_NUMBER, marker); if (line.equals("")) { //$NON-NLS-1$ locationText.setText(""); //$NON-NLS-1$ } else { locationText.setText(NLS.bind(MarkerMessages.label_lineNumber, line)); } } descriptionText.selectAll(); } /** * Updates the dialog from the predefined attributes. */ protected void updateDialogForNewMarker() { if (resource != null && resourceText != null && folderText != null) { resourceText.setText(resource.getName()); IPath path = resource.getFullPath(); int n = path.segmentCount() - 1; // n is the number of segments in container, not path if (n > 0) { int len = 0; for (int i = 0; i < n; ++i) { len += path.segment(i).length(); } // account for /'s if (n > 1) { len += n - 1; } StringBuffer sb = new StringBuffer(len); for (int i = 0; i < n; ++i) { if (i != 0) { sb.append('/'); } sb.append(path.segment(i)); } folderText.setText(sb.toString()); } } if (initialAttributes != null) { Object description = initialAttributes.get(IMarker.MESSAGE); if (description != null && description instanceof String) { descriptionText.setText((String) description); } descriptionText.selectAll(); Object line = initialAttributes.get(IMarker.LINE_NUMBER); if (line != null && locationText != null) { locationText.setText(line.toString()); } } } /** * Method declared on Dialog. */ protected void okPressed() { if (marker == null || Util.isEditable(marker)) { saveChanges(); } super.okPressed(); } /** * Sets the dialog's dirty flag to <code>true</code>. */ protected void markDirty() { dirty = true; } /** * @return <ul> * <li><code>true</code> if the dirty flag has been set to true.</li> <li><code>false</code> otherwise.</li> * </ul> */ protected boolean isDirty() { return dirty; } /** * Saves the changes made in the dialog if needed. Creates a new marker if needed. Updates the existing marker only * if there have been changes. */ @SuppressWarnings("unchecked") private void saveChanges() { Map attrs = getMarkerAttributes(); IUndoableOperation op = null; if (marker == null) { if (resource == null) return; op = new CreateMarkersOperation(type, attrs, resource, getCreateOperationTitle()); } else { if (isDirty()) { op = new UpdateMarkersOperation(marker, attrs, getModifyOperationTitle(), true); } } if (op != null) { try { PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().execute(op, null, WorkspaceUndoUtil.getUIInfoAdapter(getShell())); } catch (ExecutionException e) { if (e.getCause() instanceof CoreException) { ErrorDialog.openError(getShell(), MarkerMessages.Error, null, ((CoreException) e.getCause()).getStatus()); } else { IDEWorkbenchPlugin.log(e.getMessage(), e); } } } } /** * Returns the marker attributes to save back to the marker, based on the current dialog fields. */ @SuppressWarnings("unchecked") protected Map getMarkerAttributes() { Map attrs = getInitialAttributes(); attrs.put(IMarker.MESSAGE, descriptionText.getText()); return attrs; } /** * Updates widget enablement for the dialog. Should be overridden by subclasses. */ protected void updateEnablement() { descriptionText.setEditable(isEditable()); } /** * @return <ul> * <li><code>true</code> if the marker is editable or the dialog is creating a new marker.</li> <li><code>false * </code> if the marker is not editable.</li> * </ul> */ protected boolean isEditable() { if (marker == null) { return true; } return Util.isEditable(marker); } /** * Sets the marker type when creating a new marker. * * @param type the marker type * * @since 3.3 this method is protected. */ protected void setType(String type) { this.type = type; } /* * (non-Javadoc) * * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings() * * @since 3.2 */ protected IDialogSettings getDialogBoundsSettings() { IDialogSettings settings = IDEWorkbenchPlugin.getDefault().getDialogSettings(); IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); if (section == null) { section = settings.addNewSection(DIALOG_SETTINGS_SECTION); } return section; } /** * Return the string that describes a modify marker operation. Subclasses may override to more specifically describe * the marker. * * @since 3.3 */ protected String getModifyOperationTitle() { if (markerName == null) { // we don't know what kind of marker is being modified return MarkerMessages.DialogMarkerProperties_ModifyMarker; } return NLS.bind(MarkerMessages.qualifiedMarkerCommand_title, MarkerMessages.DialogMarkerProperties_Modify, markerName);//$NON-NLS-2$ } /** * Return the string that describes a create marker operation. Subclasses may override to more specifically describe * the marker. * * @since 3.3 */ protected String getCreateOperationTitle() { if (markerName == null) { // we don't know what kind of marker is being created return MarkerMessages.DialogMarkerProperties_CreateMarker;//$NON-NLS-1$ } return NLS.bind(MarkerMessages.qualifiedMarkerCommand_title, MarkerMessages.DialogMarkerProperties_Create, markerName);//$NON-NLS-2$ } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.Dialog#isResizable() */ protected boolean isResizable() { return true; } }