blob: 5fd07a678d0d90fee92d3614727a98e3b89671f7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation 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
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.views.bookmarkexplorer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
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.graphics.Font;
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.internal.views.bookmarkexplorer.BookmarkMessages;
/**
* Shows the properties of a new or existing bookmark
*/
class BookmarkPropertiesDialog extends Dialog {
/**
* The bookmark being shown, or <code>null</code> for a new bookmark
*/
private IMarker marker = null;
/**
* The resource on which to create a new bookmark
*/
private IResource resource = null;
/**
* The initial attributes to use when creating a new bookmark
*/
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;
/**
* Creates the dialog. By default this dialog creates a new bookmark.
* To set the resource and initial attributes for the new bookmark,
* use <code>setResource</code> and <code>setInitialAttributes</code>.
* To show or modify an existing bookmark, use <code>setMarker</code>.
*
* @param shell the parent shell
*/
public BookmarkPropertiesDialog(Shell parentShell) {
super(parentShell);
}
public BookmarkPropertiesDialog(Shell parentShell, String title) {
super(parentShell);
this.title = title;
}
public void create() {
super.create();
}
/**
* Sets the marker to show or modify.
*
* @param marker the marker, or <code>null</code> to create a new marker
*/
public void setMarker(IMarker marker) {
this.marker = marker;
}
/**
* 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.
*/
public IMarker getMarker() {
return marker;
}
/**
* Sets the resource to use when creating a new bookmark.
* If not set, the new bookmark is created on the workspace root.
*/
public void setResource(IResource resource) {
this.resource = resource;
}
/**
* Returns the resource to use when creating a new bookmark,
* or <code>null</code> if none has been set.
* If not set, the new bookmark is created on the workspace root.
*/
public IResource getResource() {
return resource;
}
/**
* Sets initial attributes to use when creating a new bookmark.
* If not set, the new bookmark is created with default attributes.
*/
public void setInitialAttributes(Map initialAttributes) {
this.initialAttributes = initialAttributes;
}
/**
* Returns the initial attributes to use when creating a new bookmark,
* or <code>null</code> if not set.
* If not set, the new bookmark is created with default attributes.
*/
public Map getInitialAttributes() {
return initialAttributes;
}
/* (non-Javadoc)
* Method declared on Window.
*/
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
if (title == null)
newShell.setText(BookmarkMessages.PropertiesDialogTitle_text);
else
newShell.setText(title);
}
/* (non-Javadoc)
* 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) {
}
} else if (initialAttributes == null && resource == null) {
resource = ResourcesPlugin.getWorkspace().getRoot();
}
Composite composite = (Composite) super.createDialogArea(parent);
initializeDialogUnits(composite);
createDescriptionArea(composite);
if (marker != null)
createCreationTimeArea(composite);
if (resource != null && resource.getType() != IResource.ROOT)
createResourceArea(composite);
updateDialogFromMarker();
return composite;
}
/**
* Method createCreationTimeArea.
* @param composite
*/
private void createCreationTimeArea(Composite parent) {
String creation = BookmarkMessages.MarkerCreationTime_text;
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
composite.setLayout(layout);
Label label = new Label(composite, SWT.NONE);
label.setText(creation);
label.setFont(font);
creationTime = new Label(composite, SWT.NONE);
creationTime.setFont(font);
}
/**
* 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) {
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
composite.setLayout(layout);
Label label = new Label(composite, SWT.NONE);
label.setText(BookmarkMessages.ColumnDescription_dialogText);
label.setFont(font);
int style = SWT.SINGLE | SWT.BORDER;
descriptionText = new Text(composite, style);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.widthHint = convertHorizontalDLUsToPixels(400);
descriptionText.setLayoutData(gridData);
descriptionText.setFont(font);
descriptionText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
markDirty();
}
});
}
/**
* Creates the area for the Resource field.
*/
private void createResourceArea(Composite parent) {
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NONE);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
composite.setLayoutData(gridData);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
composite.setLayout(layout);
Label resourceLabel = new Label(composite, SWT.NONE);
resourceLabel.setText(BookmarkMessages.ColumnResource_dialogText);
resourceLabel.setFont(font);
resourceText = new Text(composite, SWT.SINGLE | SWT.WRAP
| SWT.READ_ONLY | SWT.BORDER);
gridData = new GridData(GridData.FILL_HORIZONTAL);
resourceText.setLayoutData(gridData);
resourceText.setFont(font);
Label folderLabel = new Label(composite, SWT.NONE);
folderLabel.setText(BookmarkMessages.ColumnFolder_dialogText);
folderLabel.setFont(font);
folderText = new Text(composite, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY
| SWT.BORDER);
gridData = new GridData(GridData.FILL_HORIZONTAL);
folderText.setLayoutData(gridData);
folderText.setFont(font);
Label locationLabel = new Label(composite, SWT.NONE);
locationLabel.setText(BookmarkMessages.ColumnLocation_dialogText);
locationLabel.setFont(font);
locationText = new Text(composite, SWT.SINGLE | SWT.WRAP
| SWT.READ_ONLY | SWT.BORDER);
gridData = new GridData(GridData.FILL_HORIZONTAL);
locationText.setLayoutData(gridData);
locationText.setFont(font);
}
/**
* Updates the dialog from the marker state.
*/
private void updateDialogFromMarker() {
if (marker == null) {
updateDialogForNewMarker();
return;
}
descriptionText.setText(MarkerUtil.getMessage(marker));
if (creationTime != null)
creationTime.setText(MarkerUtil.getCreationTime(marker));
if (resourceText != null)
resourceText.setText(MarkerUtil.getResourceName(marker));
if (folderText != null)
folderText.setText(MarkerUtil.getContainerName(marker));
if (locationText != null) {
int line = MarkerUtil.getLineNumber(marker);
if (line < 0)
locationText.setText(""); //$NON-NLS-1$
else
locationText.setText(NLS.bind(BookmarkMessages.LineIndicator_text, String.valueOf(line)));
}
descriptionText.selectAll();
}
void updateDialogForNewMarker() {
if (resource != 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 && line instanceof Integer)
locationText.setText(NLS.bind(BookmarkMessages.LineIndicator_text, line));
}
}
/* (non-Javadoc)
* Method declared on Dialog
*/
protected void okPressed() {
saveChanges();
super.okPressed();
}
private void markDirty() {
dirty = true;
}
private boolean isDirty() {
return dirty;
}
/**
* Saves the changes made in the dialog if needed.
* Creates a new bookmark if needed.
* Updates the existing bookmark only if there have been changes.
*/
private void saveChanges() {
try {
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
if (marker == null)
createMarker();
else if (isDirty())
updateMarker();
}
}, null);
} catch (CoreException e) {
ErrorDialog.openError(getShell(), BookmarkMessages.Error_text, null, e.getStatus());
return;
}
}
/**
* Creates or updates the marker. Must be called within a workspace runnable.
*/
private void updateMarker() throws CoreException {
// Set the marker attributes from the current dialog field values.
// Do not use setAttributes(Map) as that overwrites any attributes
// not covered by the dialog.
Map attrs = getMarkerAttributesFromDialog();
for (Iterator i = attrs.keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
Object val = attrs.get(key);
marker.setAttribute(key, val);
}
}
/**
* Returns the marker attributes to save back to the marker,
* based on the current dialog fields.
*/
private Map getMarkerAttributesFromDialog() {
Map attribs = new HashMap();
attribs.put(IMarker.MESSAGE, descriptionText.getText());
return attribs;
}
private void createMarker() {
if (resource == null || !(resource instanceof IFile))
return;
IFile file = (IFile) resource;
try {
IMarker newMarker = file.createMarker(IMarker.BOOKMARK);
if (initialAttributes != null)
newMarker.setAttributes(initialAttributes);
String message = descriptionText.getText();
newMarker.setAttribute(IMarker.MESSAGE, message);
} catch (CoreException e) {
}
}
}