com.google.dart.tools.ui.feedback.FeedbackDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.google.dart.tools.ui.feedback.FeedbackDialog.java

Source

/*
 * Copyright (c) 2012, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.dart.tools.ui.feedback;

import com.google.dart.tools.ui.DartToolsPlugin;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import java.lang.reflect.InvocationTargetException;

/**
 * A dialog to collect user feedback.
 */
public class FeedbackDialog extends Dialog implements IRunnableContext, DisposeListener {

    /**
     * Key used to retrieve stored settings from the activator's cache.
     */
    private static final String DIALOG_SETTING_CACHE_KEY = FeedbackDialog.class.getSimpleName();

    /**
     * Key for caching opt-in setting state.
     */
    private static final String OPT_IN_SETTING_KEY = "opt.in.enabled"; //$NON-NLS-1$

    private Button okButton;
    private Text feedbackText;
    private Button sendAdditionalDataButton;
    private Link previewDataLink;

    private ProgressMonitorPart progressMonitorPart;

    /**
     * FeedbackReport report for preview and submission.
     */
    private final FeedbackReport feedbackReport;

    /**
     * Feedback image, cached for proper disposal.
     */
    private Image feedbackImage;

    /**
     * Create the feedback dialog.
     * 
     * @param parentShell the parent shell
     * @param productName the name of the installed product (e.g., "Editor" vs. "Editor Plugin")
     */
    public FeedbackDialog(Shell parentShell, String productName) {
        super(parentShell);
        feedbackReport = new FeedbackReport(productName);
    }

    @Override
    public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
            throws InvocationTargetException, InterruptedException {
        progressMonitorPart.getParent().setVisible(true);
        ModalContext.run(runnable, fork, progressMonitorPart, getShell().getDisplay());
    }

    @Override
    public void widgetDisposed(DisposeEvent e) {
        if (feedbackImage != null) {
            feedbackImage.dispose();
        }
    }

    @Override
    protected void buttonPressed(int buttonId) {
        updateFeedbackTextForClick(buttonId);
        super.buttonPressed(buttonId);
    }

    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(FeedbackMessages.FeedbackDialog_Title);
        newShell.addDisposeListener(this);
    }

    @Override
    protected Control createButtonBar(Composite parent) {
        //overriding to tweak layout

        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 0; // this is incremented by createButton
        layout.makeColumnsEqualWidth = true;
        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
        layout.marginHeight = 0; //convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        layout.verticalSpacing = 0; //convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        //put some padding at the bottom
        layout.marginBottom = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        composite.setLayout(layout);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
        composite.setLayoutData(data);
        composite.setFont(parent.getFont());

        // Add the buttons to the button bar.
        createButtonsForButtonBar(composite);
        return composite;
    }

    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        okButton = createButton(parent, IDialogConstants.OK_ID, FeedbackMessages.FeedbackDialog_OK_Button_Text,
                true);
        createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
        updateEnablement();
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        Composite container = (Composite) super.createDialogArea(parent);
        Composite composite = new Composite(container, SWT.NONE);
        GridLayout gl_composite = new GridLayout(2, false);
        gl_composite.marginHeight = 0;
        composite.setLayout(gl_composite);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

        Label imageLabel = new Label(composite, SWT.NONE);
        GridData data = new GridData(SWT.CENTER, SWT.TOP, false, false, 1, 1);
        data.verticalSpan = 2;
        imageLabel.setLayoutData(data);
        ImageDescriptor imageDescriptor = DartToolsPlugin.getImageDescriptor("icons/insert_comment.png"); //$NON-NLS-1$
        feedbackImage = imageDescriptor.createImage();
        imageLabel.setImage(feedbackImage);

        Label inviteText = new Label(composite, SWT.NONE);
        inviteText.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1));
        inviteText.setText(FeedbackMessages.FeedbackDialog_Description_Text);

        feedbackText = new Text(composite, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
        gd.minimumWidth = 420;
        gd.minimumHeight = 160;
        feedbackText.setLayoutData(gd);

        //spacer
        new Label(composite, SWT.NONE);

        Composite logOptinComposite = new Composite(composite, SWT.NONE);
        logOptinComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        GridLayout gl_logOptinComposite = new GridLayout(2, false);
        gl_logOptinComposite.marginWidth = 0;
        gl_logOptinComposite.horizontalSpacing = 0;
        gl_logOptinComposite.verticalSpacing = 0;
        gl_logOptinComposite.marginHeight = 0;
        logOptinComposite.setLayout(gl_logOptinComposite);

        sendAdditionalDataButton = new Button(logOptinComposite, SWT.CHECK);
        sendAdditionalDataButton.setText(FeedbackMessages.FeedbackDialog_send_additional_data_optin_Text);

        previewDataLink = new Link(logOptinComposite, SWT.NONE);
        GridData gd_1 = new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1);
        gd_1.verticalIndent = 2;
        previewDataLink.setLayoutData(gd_1);
        previewDataLink.setText(FeedbackMessages.FeedbackDialog_link_text);

        //spacer
        new Label(composite, SWT.NONE);

        Composite monitorComposite = new Composite(composite, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.numColumns = 2;
        monitorComposite.setLayout(layout);
        monitorComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        GridLayout pmLayout = new GridLayout();
        progressMonitorPart = new ProgressMonitorPart(monitorComposite, pmLayout, false);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        progressMonitorPart.setLayoutData(gd);
        monitorComposite.setVisible(false);
        new Label(monitorComposite, SWT.NONE);

        restoreSettings();
        hookupListeners();

        return container;
    }

    /**
     * Return the dialog store to cache values into
     */
    protected IDialogSettings getDialogSettings() {
        IDialogSettings bundleSettings = DartToolsPlugin.getDefault().getDialogSettings();
        IDialogSettings dialogSettings = bundleSettings.getSection(DIALOG_SETTING_CACHE_KEY);
        if (dialogSettings == null) {
            dialogSettings = bundleSettings.addNewSection(DIALOG_SETTING_CACHE_KEY);
        }
        return dialogSettings;
    }

    @Override
    protected int getShellStyle() {
        return SWT.ON_TOP | SWT.MODELESS | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.RESIZE;
    }

    @Override
    protected boolean isResizable() {
        return true;
    }

    @Override
    protected void okPressed() {
        try {
            if (submitFeedback().isOK()) {
                saveSettings();
                super.okPressed();
                MessageDialog.openInformation(getParentShell(), FeedbackMessages.FeedbackDialog_feedback_sent_label,
                        FeedbackMessages.FeedbackDialog_feedback_sent_details);
                return;
            }
        } catch (Throwable th) {
            DartToolsPlugin.log(th);
        }
        MessageDialog.openError(getParentShell(), FeedbackMessages.FeedbackDialog_error_submitting_label,
                FeedbackMessages.FeedbackDialog_error_submitting_detail);
        setReturnCode(CANCEL);
    }

    /**
     * Update button and link enablement.
     */
    protected void updateEnablement() {
        // Controls are null during dialog creation
        if (okButton != null) {
            boolean hasContent = !feedbackText.getText().isEmpty();
            okButton.setEnabled(hasContent);
        }
    }

    private void hookupListeners() {
        feedbackText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updateEnablement();
            }
        });
        previewDataLink.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                try {
                    LogViewer logViewer = new LogViewer(getShell(),
                            feedbackReport.getDetailString(sendAdditionData()));

                    logViewer.open();
                } catch (Throwable th) {
                    MessageDialog.openError(getParentShell(),
                            FeedbackMessages.FeedbackDialog_error_opening_log_label,
                            FeedbackMessages.FeedbackDialog_error_opening_log_detail);
                }
            }
        });
        sendAdditionalDataButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateEnablement();
            }
        });
    }

    private void restoreSettings() {
        sendAdditionalDataButton.setSelection(getDialogSettings().getBoolean(OPT_IN_SETTING_KEY));
    }

    private void saveSettings() {
        getDialogSettings().put(OPT_IN_SETTING_KEY, sendAdditionData());
    }

    private boolean sendAdditionData() {
        return sendAdditionalDataButton.getSelection();
    }

    private IStatus submitFeedback() {
        final IStatus[] status = new IStatus[1];

        try {
            run(false, false, new IRunnableWithProgress() {
                @Override
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    status[0] = new FeedbackSubmissionJob(new FeedbackWriter(feedbackReport, sendAdditionData()))
                            .run(monitor);
                }
            });
        } catch (InvocationTargetException e) {
            status[0] = DartToolsPlugin.createErrorStatus(e.getMessage());
        } catch (InterruptedException e) {
            status[0] = DartToolsPlugin.createErrorStatus(e.getMessage());
        }

        return status[0];

    }

    private void updateFeedbackTextForClick(int buttonId) {
        feedbackReport.setFeedbackText(buttonId == IDialogConstants.OK_ID ? feedbackText.getText() : "");
    }
}