org.eclipse.ui.ide.dialogs.ResourceEncodingFieldEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ui.ide.dialogs.ResourceEncodingFieldEditor.java

Source

/*******************************************************************************
 * Copyright (c) 2004, 2010 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.ide.dialogs;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.WorkbenchEncoding;
import org.eclipse.ui.ide.IDEEncoding;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * The ResourceEncodingFieldEditor is a field editor for editing the encoding of
 * a resource and does not use a preference store.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * 
 * @since 3.1
 */
public final class ResourceEncodingFieldEditor extends AbstractEncodingFieldEditor {

    /**
     * The resource being edited.
     */
    private IResource resource;

    private Composite group;

    private Button separateDerivedEncodingsButton = null;

    /**
     * Creates a new encoding field editor for setting the encoding on the given
     * resource.
     * 
     * @param labelText
     *            the label text of the field editor
     * @param parent
     *            the parent of the field editor's control
     * @param charsetResource
     *            must be an <code>IContainer</code> or an <code>IFile</code>.
     * 
     * @see org.eclipse.core.resources.IContainer#getDefaultCharset()
     * @see org.eclipse.core.resources.IFile#getCharset()
     */
    public ResourceEncodingFieldEditor(String labelText, Composite parent, IResource charsetResource) {
        super();
        setLabelAndResource(labelText, charsetResource);
        createControl(parent);
    }

    /**
     * Creates a new encoding field editor for setting the encoding on the given
     * resource.
     * 
     * @param labelText
     *            the label text of the field editor
     * @param parent
     *            the parent of the field editor's control
     * @param charsetResource
     *            must be an <code>IContainer</code> or an <code>IFile</code>.
     *  @param groupTitle
     *          the title for the field editor's control. If groupTitle is
     *            <code>null</code> the control will be unlabelled
     *            (by default a {@link Composite} instead of a {@link Group}.
     * 
     * @see org.eclipse.core.resources.IContainer#getDefaultCharset()
     * @see org.eclipse.core.resources.IFile#getCharset()
     * @see AbstractEncodingFieldEditor#setGroupTitle(String)
     * @since 3.3
     */
    public ResourceEncodingFieldEditor(String labelText, Composite parent, IResource charsetResource,
            String groupTitle) {
        super();
        setLabelAndResource(labelText, charsetResource);
        setGroupTitle(groupTitle);
        createControl(parent);
    }

    /**
      * Set the label text and the resource we are editing.
     * @param labelText
     * @param charsetResource
      * @since 3.3
     */
    private void setLabelAndResource(String labelText, IResource charsetResource) {
        Assert.isTrue(charsetResource instanceof IContainer || charsetResource instanceof IFile);
        setLabelText(labelText);
        this.resource = charsetResource;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.internal.ide.dialogs.AbstractEncodingFieldEditor#getStoredValue()
     */
    protected String getStoredValue() {
        try {
            if (resource instanceof IContainer) {
                return ((IContainer) resource).getDefaultCharset(false);
            }
            return ((IFile) resource).getCharset(false);

        } catch (CoreException e) {// If there is an error return the default
            IDEWorkbenchPlugin.log(IDEWorkbenchMessages.ResourceEncodingFieldEditor_ErrorLoadingMessage,
                    e.getStatus());
            return WorkbenchEncoding.getWorkbenchDefaultEncoding();
        }

    }

    private boolean getStoredSeparateDerivedEncodingsValue() {
        // be careful looking up for our node so not to create any nodes as side effect
        Preferences node = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE);
        String projectName = ((IProject) resource).getName();
        try {
            //TODO once bug 90500 is fixed, should be as simple as this:
            //         String path = projectName + IPath.SEPARATOR + ResourcesPlugin.PI_RESOURCES;
            //         return node.nodeExists(path) ? node.node(path).getBoolean(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, false) : false;
            // for now, take the long way
            if (!node.nodeExists(projectName))
                return false;
            node = node.node(projectName);
            if (!node.nodeExists(ResourcesPlugin.PI_RESOURCES))
                return false;
            node = node.node(ResourcesPlugin.PI_RESOURCES);
            return node.getBoolean(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, false);
        } catch (BackingStoreException e) {
            // default value
            return false;
        }
    }

    private boolean hasSameSeparateDerivedEncodings() {
        return (separateDerivedEncodingsButton == null) || ((separateDerivedEncodingsButton != null)
                && (separateDerivedEncodingsButton.getSelection() == getStoredSeparateDerivedEncodingsValue()));
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.preference.FieldEditor#doStore()
     */
    protected void doStore() {

        String encoding = getSelectedEncoding();

        // Clear the value if nothing is selected
        if (isDefaultSelected()) {
            encoding = null;
        }
        // Don't update if the same thing is selected
        final boolean hasSameEncoding = hasSameEncoding(encoding);
        final boolean hasSameSeparateDerivedEncodings = hasSameSeparateDerivedEncodings();
        if (hasSameEncoding && hasSameSeparateDerivedEncodings) {
            return;
        }

        String descriptionCharset = getCharsetFromDescription();
        if (descriptionCharset != null && !(descriptionCharset.equals(encoding)) && encoding != null) {
            Shell shell = null;
            DialogPage page = getPage();
            if (page != null) {
                shell = page.getShell();
            }

            MessageDialog dialog = new MessageDialog(shell,
                    IDEWorkbenchMessages.ResourceEncodingFieldEditor_EncodingConflictTitle, null,
                    NLS.bind(IDEWorkbenchMessages.ResourceEncodingFieldEditor_EncodingConflictMessage, encoding,
                            descriptionCharset),
                    MessageDialog.WARNING, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL },
                    0) {
                protected int getShellStyle() {
                    return super.getShellStyle() | SWT.SHEET;
                }
            }; // yes is the
               // default
            if (dialog.open() > 0) {
                return;
            }
        }

        IDEEncoding.addIDEEncoding(encoding);

        final String finalEncoding = encoding;

        Job charsetJob = new Job(IDEWorkbenchMessages.IDEEncoding_EncodingJob) {
            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
             */
            protected IStatus run(IProgressMonitor monitor) {
                try {
                    if (!hasSameEncoding) {
                        if (resource instanceof IContainer) {
                            ((IContainer) resource).setDefaultCharset(finalEncoding, monitor);
                        } else {
                            ((IFile) resource).setCharset(finalEncoding, monitor);
                        }
                    }
                    if (!hasSameSeparateDerivedEncodings) {
                        Preferences prefs = new ProjectScope((IProject) resource)
                                .getNode(ResourcesPlugin.PI_RESOURCES);
                        if (getStoredSeparateDerivedEncodingsValue())
                            prefs.remove(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS);
                        else
                            prefs.putBoolean(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, true);
                        prefs.flush();
                    }
                    return Status.OK_STATUS;
                } catch (CoreException e) {// If there is an error return the
                    // default
                    IDEWorkbenchPlugin.log(IDEWorkbenchMessages.ResourceEncodingFieldEditor_ErrorStoringMessage,
                            e.getStatus());
                    return e.getStatus();
                } catch (BackingStoreException e) {
                    IDEWorkbenchPlugin.log(IDEWorkbenchMessages.ResourceEncodingFieldEditor_ErrorStoringMessage, e);
                    return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, e.getMessage(), e);
                }
            }
        };

        charsetJob.schedule();

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.preference.FieldEditor#store()
     */
    public void store() {
        // Override the store method as we are not using a preference store
        doStore();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.preference.FieldEditor#load()
     */
    public void load() {
        // Override the load method as we are not using a preference store
        setPresentsDefaultValue(false);
        doLoad();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.preference.FieldEditor#loadDefault()
     */
    public void loadDefault() {
        // Override the loadDefault method as we are not using a preference store
        setPresentsDefaultValue(true);
        doLoadDefault();
        refreshValidState();
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault()
     */
    protected void doLoadDefault() {
        super.doLoadDefault();
        if (separateDerivedEncodingsButton != null)
            separateDerivedEncodingsButton.setSelection(getStoredSeparateDerivedEncodingsValue());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.ide.dialogs.AbstractEncodingFieldEditor#findDefaultEncoding()
     */
    protected String findDefaultEncoding() {

        if (resource instanceof IWorkspaceRoot) {
            return super.findDefaultEncoding();
        }

        String defaultCharset = getCharsetFromDescription();

        if (defaultCharset != null && defaultCharset.length() > 0) {
            return defaultCharset;
        }
        try {
            // Query up the whole hierarchy
            defaultCharset = resource.getParent().getDefaultCharset(true);
        } catch (CoreException exception) {
            // If there is an exception try again
        }

        if (defaultCharset != null && defaultCharset.length() > 0) {
            return defaultCharset;
        }

        return super.findDefaultEncoding();
    }

    /**
     * Returns the charset from the content description if there is one.
     * 
     * @return the charset from the content description, or <code>null</code>
     */
    private String getCharsetFromDescription() {
        IContentDescription description = getContentDescription();
        if (description != null) {
            return description.getCharset();
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.ide.dialogs.AbstractEncodingFieldEditor#defaultButtonText()
     */
    protected String defaultButtonText() {

        if (resource instanceof IWorkspaceRoot) {
            return super.defaultButtonText();
        }

        if (resource instanceof IFile) {
            try {
                IContentDescription description = ((IFile) resource).getContentDescription();
                // If we can find a charset from the description then derive
                // from that
                if (description == null || description.getCharset() == null) {
                    return NLS.bind(IDEWorkbenchMessages.ResourceInfo_fileContainerEncodingFormat, getDefaultEnc());
                }

                IContentType contentType = description.getContentType();
                if (contentType != null && contentType.getDefaultCharset() == description.getCharset()) {
                    return NLS.bind(IDEWorkbenchMessages.ResourceInfo_fileContentTypeEncodingFormat,
                            getDefaultEnc());
                }

                return NLS.bind(IDEWorkbenchMessages.ResourceInfo_fileContentEncodingFormat, getDefaultEnc());

            } catch (CoreException exception) {
                // Do nothing here as we will just try to derive from the
                // container
            }
        }

        return NLS.bind(IDEWorkbenchMessages.ResourceInfo_containerEncodingFormat, getDefaultEnc());

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.ide.dialogs.AbstractEncodingFieldEditor#createEncodingGroup(org.eclipse.swt.widgets.Composite,
     *      int)
     */
    protected Composite createEncodingGroup(Composite parent, int numColumns) {
        group = super.createEncodingGroup(parent, numColumns);
        String byteOrderLabel = IDEEncoding.getByteOrderMarkLabel(getContentDescription());
        if (byteOrderLabel != null) {
            Label label = new Label(group, SWT.NONE);
            label.setText(
                    NLS.bind(IDEWorkbenchMessages.WorkbenchPreference_encoding_encodingMessage, byteOrderLabel));
            GridData layoutData = new GridData();
            layoutData.horizontalSpan = numColumns + 1;
            label.setLayoutData(layoutData);

        }

        if (resource.getType() == IResource.PROJECT) {
            separateDerivedEncodingsButton = new Button(group, SWT.CHECK);
            GridData data = new GridData();
            data.horizontalSpan = 2;
            separateDerivedEncodingsButton.setLayoutData(data);
            separateDerivedEncodingsButton
                    .setText(IDEWorkbenchMessages.ResourceEncodingFieldEditor_SeparateDerivedEncodingsLabel);
            separateDerivedEncodingsButton.setSelection(getStoredSeparateDerivedEncodingsValue());
        }
        return group;
    }

    /**
     * Returns the content description of the resource if it is a file and it
     * has a content description.
     * 
     * @return the content description or <code>null</code> if resource is not
     *         an <code>IFile</code> or it does not have a description
     */
    private IContentDescription getContentDescription() {
        try {
            if (resource instanceof IFile) {
                return (((IFile) resource).getContentDescription());
            }
        } catch (CoreException exception) {
            // If we cannot find it return null
        }
        return null;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.preference.FieldEditor#setEnabled(boolean, org.eclipse.swt.widgets.Composite)
     */
    public void setEnabled(boolean enabled, Composite parent) {
        super.setEnabled(enabled, parent);
        group.setEnabled(enabled);
        Control[] children = group.getChildren();
        for (int i = 0; i < children.length; i++) {
            children[i].setEnabled(enabled);

        }
    }

}