org.eclipse.mylyn.internal.tasks.ui.wizards.AttachmentSourcePage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mylyn.internal.tasks.ui.wizards.AttachmentSourcePage.java

Source

/*******************************************************************************
 * Copyright (c) 2004, 2009 Tasktop Technologies 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
 *     Sebastian Davids <sdavids@gmx.de> - layout tweaks
 *     Jeff Pound - modified for attachment input
 *     Chris Aniszczyk <caniszczyk@gmail.com> - bug 20957
 *     Tasktop Technologies - improvements
 *******************************************************************************/

package org.eclipse.mylyn.internal.tasks.ui.wizards;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceMappingContext;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard.ClipboardTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

/**
 * A wizard to input the source of the attachment.
 * <p>
 * Based on org.eclipse.compare.internal.InputPatchPage.
 */
public class AttachmentSourcePage extends WizardPage {

    // constants
    protected static final int SIZING_TEXT_FIELD_WIDTH = 250;

    protected static final int COMBO_HISTORY_LENGTH = 5;

    // input constants
    protected final static int CLIPBOARD = 1;

    protected final static int FILE = 2;

    protected final static int WORKSPACE = 3;

    protected final static int SCREENSHOT = 4;

    static final char SEPARATOR = System.getProperty("file.separator").charAt(0); //$NON-NLS-1$

    private boolean showError = false;

    // SWT widgets
    private Button useClipboardButton;

    //   private Button useScreenshotButton;

    private Combo fileNameField;

    private Button fileBrowseButton;

    private Button useFileButton;

    private Button useWorkspaceButton;

    private Label workspaceSelectLabel;

    private TreeViewer treeViewer;

    private String clipboardContents;

    private boolean initUseClipboard = false;

    private final String DIALOG_SETTINGS = "InputAttachmentSourcePage"; //$NON-NLS-1$

    private final String S_LAST_SELECTION = "lastSelection"; //$NON-NLS-1$

    private final String S_FILE_HISTORY = "fileHistory"; //$NON-NLS-1$

    private final String S_LAST_FILE = "lastFile"; //$NON-NLS-1$

    private final TaskAttachmentModel model;

    /**
     * The last filename that was selected through the browse button.
     */
    private String lastFilename;

    public AttachmentSourcePage(TaskAttachmentModel model) {
        super("InputAttachmentPage"); //$NON-NLS-1$
        this.model = model;
        setTitle(Messages.AttachmentSourcePage_Select_attachment_source);
        setDescription(Messages.AttachmentSourcePage_Clipboard_supports_text_and_image_attachments_only);
        // setMessage("Please select the source for the attachment");
    }

    private void restoreDialogSettings() {
        IDialogSettings settings = getDialogSettings();
        if (settings == null) {
            updateWidgetEnablements();
            return;
        }

        String selection = settings.get(S_LAST_SELECTION);
        if (selection != null) {
            setInputMethod(Integer.valueOf(selection).intValue());
        } else {
            updateWidgetEnablements();
        }

        String[] fileNames = settings.getArray(S_FILE_HISTORY);
        if (fileNames != null) {
            // destination
            for (String fileName : fileNames) {
                fileNameField.add(fileName);
            }
        }
        lastFilename = settings.get(S_LAST_FILE);
    }

    /*
     * Get a path from the supplied text widget. @return
     * org.eclipse.core.runtime.IPath
     */
    protected IPath getPathFromText(Text textField) {
        return (new Path(textField.getText())).makeAbsolute();
    }

    public String getAttachmentName() {
        if (getInputMethod() == CLIPBOARD) {
            return Messages.AttachmentSourcePage__Clipboard_;
        } else if (getInputMethod() == WORKSPACE) {
            return getResources(treeViewer.getSelection())[0].getFullPath().toOSString();
        }
        return getAttachmentFilePath();
    }

    public void createControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NULL);
        composite.setLayout(new GridLayout());
        GridData gd = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
        gd.heightHint = 800;
        composite.setLayoutData(gd);
        setControl(composite);

        initializeDialogUnits(parent);

        createAttachmentFileGroup(composite);

        // No error for dialog opening
        showError = false;
        clearErrorMessage();
        restoreDialogSettings();

        Dialog.applyDialogFont(composite);
    }

    @Override
    public IWizardPage getNextPage() {
        AbstractTaskAttachmentSource source = getSource();
        model.setSource(source);
        if (source != null) {
            model.setContentType(source.getContentType());
        }
        saveDialogSettings();
        return super.getNextPage();
    }

    private void saveDialogSettings() {
        IDialogSettings settings = getDialogSettings();
        settings.put(S_LAST_SELECTION, getInputMethod());

        String[] fileNames = settings.getArray(S_FILE_HISTORY);
        String newFileName = fileNameField.getText().trim();
        if (getInputMethod() == FILE && newFileName.length() > 0) {
            List<String> history = new ArrayList<String>(10);
            history.add(newFileName);
            if (fileNames != null) {
                for (int i = 0; i < fileNames.length && history.size() < COMBO_HISTORY_LENGTH; i++) {
                    if (!newFileName.equals(fileNames[i])) {
                        history.add(fileNames[i]);
                    }
                }
            }
            settings.put(S_FILE_HISTORY, history.toArray(new String[0]));
        }

        settings.put(S_LAST_FILE, lastFilename);
    }

    @Override
    public boolean canFlipToNextPage() {
        return isPageComplete();
    }

    private void setEnableAttachmentFile(boolean enable) {
        fileNameField.setEnabled(enable);
        fileBrowseButton.setEnabled(enable);
    }

    private void setEnableWorkspaceAttachment(boolean enable) {
        workspaceSelectLabel.setEnabled(enable);
        treeViewer.getTree().setEnabled(enable);
    }

    /*
     * Create the group for selecting the attachment file
     */
    private void createAttachmentFileGroup(Composite parent) {
        final Composite composite = new Composite(parent, SWT.NULL);
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        composite.setLayout(gridLayout);
        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // new row
        GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        useFileButton = new Button(composite, SWT.RADIO);
        useFileButton.setText(Messages.AttachmentSourcePage_File);

        fileNameField = new Combo(composite, SWT.BORDER);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.widthHint = SIZING_TEXT_FIELD_WIDTH;
        fileNameField.setLayoutData(gd);
        fileNameField.setText(""); //$NON-NLS-1$

        fileBrowseButton = new Button(composite, SWT.PUSH);
        fileBrowseButton.setText(Messages.AttachmentSourcePage_Browse_);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
        Point minSize = fileBrowseButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
        data.widthHint = Math.max(widthHint, minSize.x);
        fileBrowseButton.setLayoutData(data);

        // new row      
        gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        gd.horizontalSpan = 3;
        useClipboardButton = new Button(composite, SWT.RADIO);
        useClipboardButton.setText(Messages.AttachmentSourcePage_Clipboard);
        useClipboardButton.setLayoutData(gd);
        useClipboardButton.setSelection(initUseClipboard);

        // new row
        useWorkspaceButton = new Button(composite, SWT.RADIO);
        useWorkspaceButton.setText(Messages.AttachmentSourcePage_Workspace);
        gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        useWorkspaceButton.setLayoutData(gd);

        addWorkspaceControls(parent);

        // Add listeners
        useClipboardButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (!useClipboardButton.getSelection()) {
                    return;
                }

                clearErrorMessage();
                showError = true;
                storeClipboardContents();
                updateWidgetEnablements();
            }
        });

        useFileButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (!useFileButton.getSelection()) {
                    return;
                }
                // If there is anything typed in at all
                clearErrorMessage();
                showError = (fileNameField.getText() != ""); //$NON-NLS-1$
                updateWidgetEnablements();
            }
        });
        fileNameField.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                setSourceName(fileNameField.getText());
                updateWidgetEnablements();
            }
        });
        fileNameField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                clearErrorMessage();
                showError = true;
                updateWidgetEnablements();
            }
        });
        fileBrowseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                clearErrorMessage();
                showError = true;

                FileDialog fileChooser = new FileDialog(composite.getShell(), SWT.OPEN);
                fileChooser.setText(Messages.AttachmentSourcePage_Select_File_Dialog_Title);
                if (fileNameField.getText().trim().length() > 0) {
                    lastFilename = fileNameField.getText().trim();
                }
                fileChooser.setFileName(lastFilename);
                String file = fileChooser.open();
                if (file == null) {
                    return;
                }

                // remember the last selected directory 
                lastFilename = file;
                fileNameField.setText(file);
                updateWidgetEnablements();
            }
        });
        useWorkspaceButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (!useWorkspaceButton.getSelection()) {
                    return;
                }
                clearErrorMessage();
                // If there is anything typed in at all
                showError = (!treeViewer.getSelection().isEmpty());
                updateWidgetEnablements();
            }
        });

        treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                clearErrorMessage();
                updateWidgetEnablements();
            }
        });

        treeViewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                ISelection selection = event.getSelection();
                if (selection instanceof TreeSelection) {
                    TreeSelection treeSel = (TreeSelection) selection;
                    Object res = treeSel.getFirstElement();
                    if (res != null) {
                        if (res instanceof IProject || res instanceof IFolder) {
                            if (treeViewer.getExpandedState(res)) {
                                treeViewer.collapseToLevel(res, 1);
                            } else {
                                treeViewer.expandToLevel(res, 1);
                            }
                        } else if (res instanceof IFile) {
                            getContainer().showPage(getNextPage());
                        }
                    }
                }
            }
        });

        useFileButton.setSelection(!initUseClipboard);
        setEnableWorkspaceAttachment(false);
    }

    private void addWorkspaceControls(Composite composite) {

        Composite newComp = new Composite(composite, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginLeft = 16; // align w/ lable of check button
        newComp.setLayout(layout);
        newComp.setLayoutData(new GridData(GridData.FILL_BOTH));

        workspaceSelectLabel = new Label(newComp, SWT.LEFT);
        workspaceSelectLabel.setText(Messages.AttachmentSourcePage_Select_the_location_of_the_attachment);

        treeViewer = new TreeViewer(newComp, SWT.BORDER);
        treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        treeViewer.setLabelProvider(new WorkbenchLabelProvider());
        treeViewer.setContentProvider(new WorkbenchContentProvider());
        treeViewer.setComparator(new ResourceComparator(ResourceComparator.NAME));
        treeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
    }

    /**
     * Updates the enable state of this page's controls.
     */
    private void updateWidgetEnablements() {

        String error = null;

        boolean attachmentFound = false;
        int inputMethod = getInputMethod();
        if (inputMethod == CLIPBOARD) {
            if (ClipboardTaskAttachmentSource.isSupportedType(getControl().getDisplay())) {
                attachmentFound = true;
            } else {
                error = Messages.AttachmentSourcePage_Clipboard_contains_an_unsupported_data;
            }
        } else if (inputMethod == SCREENSHOT) {
            attachmentFound = true;
        } else if (inputMethod == FILE) {
            String path = fileNameField.getText();
            if (path != null && path.length() > 0) {
                File file = new File(path);
                attachmentFound = file.exists() && file.isFile() && file.length() > 0;
                if (!attachmentFound) {
                    error = Messages.AttachmentSourcePage_Cannot_locate_attachment_file;
                }
            } else {
                error = Messages.AttachmentSourcePage_No_file_name;
            }
        } else if (inputMethod == WORKSPACE) {
            // Get the selected attachment file (tree will only allow for one
            // selection)
            IResource[] resources = getResources(treeViewer.getSelection());
            if (resources == null || resources.length <= 0) {
                error = Messages.AttachmentSourcePage_No_file_name;
            } else {
                IResource attachmentFile = resources[0];
                if (attachmentFile != null && attachmentFile.getType() == IResource.FILE) {
                    File actualFile = attachmentFile.getRawLocation().toFile();
                    attachmentFound = actualFile.exists() && actualFile.isFile() && actualFile.length() > 0;
                    if (!attachmentFound) {
                        error = Messages.AttachmentSourcePage_Cannot_locate_attachment_file;
                    }
                }
            }
        }

        setPageComplete(attachmentFound);

        if (showError) {
            setErrorMessage(error);
        }

        setEnableAttachmentFile(inputMethod == FILE);
        setEnableWorkspaceAttachment(inputMethod == WORKSPACE);
    }

    /**
     * Sets the source name of the import to be the supplied path. Adds the name of the path to the list of items in the
     * source combo and selects it.
     * 
     * @param path
     *            the path to be added
     */
    protected void setSourceName(String path) {

        if (path.length() > 0) {

            String[] currentItems = fileNameField.getItems();
            int selectionIndex = -1;
            for (int i = 0; i < currentItems.length; i++) {
                if (currentItems[i].equals(path)) {
                    selectionIndex = i;
                }
            }

            if (selectionIndex < 0) { // not found in history
                int oldLength = currentItems.length;
                String[] newItems = new String[oldLength + 1];
                System.arraycopy(currentItems, 0, newItems, 0, oldLength);
                newItems[oldLength] = path;
                fileNameField.setItems(newItems);
                selectionIndex = oldLength;
            }
            fileNameField.select(selectionIndex);

            // resetSelection();
        }
    }

    /*
     * Clears the dialog message box
     */
    private void clearErrorMessage() {
        setErrorMessage(null);
    }

    protected int getInputMethod() {
        if (useClipboardButton == null) {
            if (initUseClipboard) {
                return CLIPBOARD;
            }
            return FILE;
        }
        if (useClipboardButton.getSelection()) {
            return CLIPBOARD;
        }
        if (useFileButton.getSelection()) {
            return FILE;
        }
        return WORKSPACE;
    }

    protected void setInputMethod(int input) {
        switch (input) {
        case WORKSPACE:
            useWorkspaceButton.setSelection(true);
            useClipboardButton.setSelection(false);
            useFileButton.setSelection(false);
            break;
        case CLIPBOARD:
            storeClipboardContents();

            useClipboardButton.setSelection(true);
            useFileButton.setSelection(false);
            useWorkspaceButton.setSelection(false);
            break;
        default:
            useFileButton.setSelection(true);
            useWorkspaceButton.setSelection(false);
            useClipboardButton.setSelection(false);
            break;
        }
        updateWidgetEnablements();
    }

    private String getAttachmentFilePath() {
        if (fileNameField != null) {
            return fileNameField.getText();
        }
        return null;
    }

    public String getAbsoluteAttachmentPath() {
        switch (getInputMethod()) {
        case CLIPBOARD:
            return Messages.AttachmentSourcePage__Clipboard_;
        case SCREENSHOT:
            return Messages.AttachmentSourcePage__Screenshot_;
        case WORKSPACE:
            IResource[] resources = getResources(treeViewer.getSelection());
            if (resources.length > 0 && resources[0].getRawLocation() != null) {
                return resources[0].getRawLocation().toOSString();
            } else {
                return null;
            }
        case FILE:
        default:
            return getAttachmentFilePath();
        }
    }

    /*
     * Based on .eclipse.compare.internal.Utilities
     * 
     * Convenience method: extract all accessible <code>IResources</code> from
     * given selection. Never returns null.
     */
    public static IResource[] getResources(ISelection selection) {
        ArrayList<IResource> tmp = new ArrayList<IResource>();
        Class<?> type = IResource.class;
        if (selection instanceof IStructuredSelection) {
            Object[] s = ((IStructuredSelection) selection).toArray();

            for (Object o : s) {
                IResource resource = null;
                if (type.isInstance(o)) {
                    resource = (IResource) o;

                } else if (o instanceof ResourceMapping) {
                    try {
                        ResourceTraversal[] travs = ((ResourceMapping) o)
                                .getTraversals(ResourceMappingContext.LOCAL_CONTEXT, null);
                        if (travs != null) {
                            for (ResourceTraversal trav : travs) {
                                IResource[] resources = trav.getResources();
                                for (IResource resource2 : resources) {
                                    if (type.isInstance(resource2) && resource2.isAccessible()) {
                                        tmp.add(resource2);
                                    }
                                }
                            }
                        }
                    } catch (CoreException ex) {
                        // TODO handle error
                    }
                } else if (o instanceof IAdaptable) {
                    IAdaptable a = (IAdaptable) o;
                    Object adapter = a.getAdapter(IResource.class);
                    if (type.isInstance(adapter)) {
                        resource = (IResource) adapter;
                    }
                }

                if (resource != null && resource.isAccessible()) {
                    tmp.add(resource);
                }
            }
        }

        return tmp.toArray(new IResource[tmp.size()]);
    }

    private void storeClipboardContents() {
        Control c = getControl();
        if (c != null) {
            Clipboard clipboard = new Clipboard(c.getDisplay());
            Object o = clipboard.getContents(TextTransfer.getInstance());
            clipboard.dispose();
            if (o instanceof String) {
                clipboardContents = ((String) o).trim();
            }
        }
    }

    public String getClipboardContents() {
        return clipboardContents;
    }

    public void setClipboardContents(String attachContents) {
        clipboardContents = attachContents;
    }

    public void setUseClipboard(boolean b) {
        if (useClipboardButton != null) {
            useClipboardButton.setSelection(b);
        }
        initUseClipboard = b;
    }

    @Override
    protected IDialogSettings getDialogSettings() {
        TasksUiPlugin plugin = TasksUiPlugin.getDefault();
        IDialogSettings settings = plugin.getDialogSettings();
        IDialogSettings section = settings.getSection(DIALOG_SETTINGS);
        if (section == null) {
            section = settings.addNewSection(DIALOG_SETTINGS);
        }
        return section;
    }

    public AbstractTaskAttachmentSource getSource() {
        switch (getInputMethod()) {
        case CLIPBOARD:
            return new TaskAttachmentWizard.ClipboardTaskAttachmentSource();
        case WORKSPACE:
            IResource[] resources = getResources(treeViewer.getSelection());
            if (resources.length > 0) {
                return new FileTaskAttachmentSource(resources[0].getLocation().toFile());
            } else {
                return null;
            }
        default: // FILE
            return new FileTaskAttachmentSource(new File(getAttachmentFilePath()));
        }
    }

}