/*
* Copyright (c) 2014, 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.core.DartCore;
import com.google.dart.tools.ui.DartToolsPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.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;
public class FeedbackDialog2 extends Dialog {
/**
* Key used to retrieve stored settings from the activator's cache.
*/
private static final String DIALOG_SETTING_CACHE_KEY = FeedbackDialog2.class.getName();
private static final String USER_EMAIL_KEY = "user.email";
private static final String INCLUDE_DATA_KEY = "include.data";
private static final String PUBLIC_KEY = "public";
private final FeedbackReport report;
private final Image screenshot;
private Text feedbackText;
private Button includeDataCheckbox;
private Button includeScreenshotCheckbox;
private Composite dartbugComposite;
private Button dartbugCheckbox;
private Composite emailComposite;
private Text emailText;
private Label emailLabel1;
private Label emailLabel2;
private Label emailLabel3;
private ProgressMonitorPart progressBar;
private Button okButton;
private Button cancelButton;
public FeedbackDialog2(Shell parentShell, String productName, Image screenshot) {
super(parentShell);
this.report = new FeedbackReport(productName, screenshot);
this.screenshot = screenshot;
setShellStyle(SWT.SHELL_TRIM);
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("Dart Editor Feedback");
}
@Override
protected Control createButtonBar(Composite parent) {
Composite buttonBarComposite = new Composite(parent, SWT.NONE);
GridLayout gl_buttonBarComposite = new GridLayout(2, false);
gl_buttonBarComposite.marginBottom = 10;
gl_buttonBarComposite.marginRight = 10;
gl_buttonBarComposite.marginLeft = 10;
gl_buttonBarComposite.marginTop = 10;
buttonBarComposite.setLayout(gl_buttonBarComposite);
buttonBarComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
Composite legalComposite = new Composite(buttonBarComposite, SWT.NONE);
legalComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
GridLayout gl_legalComposite = new GridLayout(2, false);
gl_legalComposite.marginRight = 20;
gl_legalComposite.verticalSpacing = 0;
gl_legalComposite.marginWidth = 0;
gl_legalComposite.marginHeight = 0;
gl_legalComposite.horizontalSpacing = 0;
legalComposite.setLayout(gl_legalComposite);
Label legalLabel1 = new Label(legalComposite, SWT.NONE);
legalLabel1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
legalLabel1.setText("The information above will be sent to Google.");
Link privacyPolicyLink = new Link(legalComposite, SWT.NONE);
privacyPolicyLink.setText("See <a>Google's Privacy Policy</a>");
Link termOfServiceLink = new Link(legalComposite, SWT.NONE);
termOfServiceLink.setText("and <a>Terms of Service</a>.");
return super.createButtonBar(buttonBarComposite);
}
/**
* Create contents of the button bar.
*
* @param parent
*/
@Override
protected void createButtonsForButtonBar(Composite parent) {
okButton = createButton(parent, IDialogConstants.OK_ID, "Send Feedback", true);
cancelButton = createButton(parent, IDialogConstants.CANCEL_ID, "Cancel", false);
updateEnablement();
}
/**
* Create contents of the dialog.
*
* @param parent
*/
@Override
protected Control createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
GridLayout gl_container = new GridLayout(2, true);
gl_container.marginBottom = 10;
gl_container.marginRight = 10;
gl_container.marginLeft = 10;
gl_container.marginTop = 10;
container.setLayout(gl_container);
Label feedbackLabel = new Label(container, SWT.NONE);
feedbackLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
feedbackLabel.setText("Please help improve Dart by telling us what you think. Thanks!");
feedbackText = new Text(container, SWT.BORDER);
feedbackText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
updateEnablement();
}
});
GridData gd_feedbackText = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
gd_feedbackText.minimumHeight = 50;
feedbackText.setLayoutData(gd_feedbackText);
includeScreenshotCheckbox = new Button(container, SWT.CHECK);
GridData gd_includeScreenshot = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
gd_includeScreenshot.verticalIndent = 10;
includeScreenshotCheckbox.setLayoutData(gd_includeScreenshot);
includeScreenshotCheckbox.setText("Include screenshot");
Link screenshotLink = new Link(container, SWT.NONE);
screenshotLink.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
showScreenshot();
}
@Override
public void widgetSelected(SelectionEvent e) {
showScreenshot();
}
});
screenshotLink.setText("<a>show screenshot</a>");
includeDataCheckbox = new Button(container, SWT.CHECK);
includeDataCheckbox.setSelection(true);
GridData gd_includeDataCheckbox = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
gd_includeDataCheckbox.verticalIndent = 10;
includeDataCheckbox.setLayoutData(gd_includeDataCheckbox);
includeDataCheckbox.setText("Include additional editor data");
includeDataCheckbox.setSelection(getDialogSettings().get(INCLUDE_DATA_KEY) == null
|| getDialogSettings().getBoolean(INCLUDE_DATA_KEY));
Link dataLink = new Link(container, SWT.NONE);
dataLink.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
showData();
}
@Override
public void widgetSelected(SelectionEvent e) {
showData();
}
});
dataLink.setText("<a>show data that will be sent</a>");
dartbugComposite = new Composite(container, SWT.NONE);
GridLayout gl_dartbugComposite = new GridLayout(2, false);
gl_dartbugComposite.verticalSpacing = 0;
gl_dartbugComposite.horizontalSpacing = 0;
gl_dartbugComposite.marginWidth = 0;
gl_dartbugComposite.marginHeight = 0;
dartbugComposite.setLayout(gl_dartbugComposite);
GridData gd_dartbugComposite = new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1);
gd_dartbugComposite.verticalIndent = 10;
dartbugComposite.setLayoutData(gd_dartbugComposite);
dartbugCheckbox = new Button(dartbugComposite, SWT.CHECK);
dartbugCheckbox.setText("Yes, you may post this information on");
dartbugCheckbox.setSelection(getDialogSettings().getBoolean(PUBLIC_KEY));
Link dartbugLink = new Link(dartbugComposite, SWT.NONE);
dartbugLink.setText("<a>dartbug.com</a>");
Label dartbugLabel = new Label(dartbugComposite, SWT.NONE);
GridData gd_dartbugLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1);
gd_dartbugLabel.horizontalIndent = 20;
dartbugLabel.setLayoutData(gd_dartbugLabel);
dartbugLabel.setText("This is an open source project; we publicly track our bugs at dartbug.com");
emailComposite = new Composite(container, SWT.NONE);
GridLayout gl_emailComposite = new GridLayout(2, false);
gl_emailComposite.verticalSpacing = 0;
gl_emailComposite.marginWidth = 0;
gl_emailComposite.marginHeight = 0;
gl_emailComposite.horizontalSpacing = 0;
emailComposite.setLayout(gl_emailComposite);
GridData gd_emailComposite = new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1);
gd_emailComposite.verticalIndent = 10;
emailComposite.setLayoutData(gd_emailComposite);
emailLabel1 = new Label(emailComposite, SWT.NONE);
emailLabel1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
emailLabel1.setText("CC:");
emailText = new Text(emailComposite, SWT.BORDER);
emailText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
String userEmail = getDialogSettings().get(USER_EMAIL_KEY);
if (userEmail != null) {
emailText.setText(userEmail);
}
emailLabel2 = new Label(emailComposite, SWT.NONE);
GridData gd_emailLabel2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1);
gd_emailLabel2.horizontalIndent = 20;
emailLabel2.setLayoutData(gd_emailLabel2);
emailLabel2.setText("You may optionally add an email address. If you do and we post a bug, we will CC you on it.");
emailLabel3 = new Label(emailComposite, SWT.NONE);
GridData gd_emailLabel3 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1);
gd_emailLabel3.horizontalIndent = 20;
emailLabel3.setLayoutData(gd_emailLabel3);
emailLabel3.setText("We apologize, but we can’t respond directly to all reports, but we read each and every one.");
progressBar = new ProgressMonitorPart(container, null, 10);
GridData gd_progressBar = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
gd_progressBar.verticalIndent = 10;
progressBar.setLayoutData(gd_progressBar);
return container;
}
@Override
protected IDialogSettings getDialogBoundsSettings() {
return getDialogSettings();
}
@Override
protected Point getInitialSize() {
Point size = super.getInitialSize();
return new Point(Math.max(size.x, 760), Math.max(size.y, 400));
}
@Override
protected void okPressed() {
// Create feedback
final FeedbackSubmissionJob2 job = newFeedbackJob();
// Save settings
getDialogSettings().put(INCLUDE_DATA_KEY, includeDataCheckbox.getSelection());
getDialogSettings().put(USER_EMAIL_KEY, emailText.getText().trim());
getDialogSettings().put(PUBLIC_KEY, dartbugCheckbox.getSelection());
// Send feedback
okButton.setEnabled(false);
cancelButton.setEnabled(false);
final IStatus[] result = new IStatus[1];
try {
ModalContext.run(new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
result[0] = job.run(monitor);
}
}, true, progressBar, getShell().getDisplay());
} catch (Throwable e) {
DartCore.logError("Failed to send feedback", e);
result[0] = new Status(IStatus.ERROR, DartCore.PLUGIN_ID, e.toString(), e);
}
// Report result to the user
if (result[0].isOK()) {
super.okPressed();
MessageDialog.openInformation(
getParentShell(),
FeedbackMessages.FeedbackDialog_feedback_sent_label,
FeedbackMessages.FeedbackDialog_feedback_sent_details);
} else {
setReturnCode(CANCEL);
MessageDialog.openError(
getParentShell(),
FeedbackMessages.FeedbackDialog_error_submitting_label,
FeedbackMessages.FeedbackDialog_error_submitting_detail);
okButton.setEnabled(true);
cancelButton.setEnabled(true);
}
}
/**
* 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 IDialogSettings getDialogSettings() {
return DartToolsPlugin.getDefault().getDialogSettingsSection(DIALOG_SETTING_CACHE_KEY);
}
private FeedbackSubmissionJob2 newFeedbackJob() {
report.setFeedbackText(feedbackText.getText());
String userEmail = emailText.getText().trim();
if (userEmail != null && userEmail.length() > 0) {
report.setUserEmail(userEmail);
}
return new FeedbackSubmissionJob2(
report,
includeDataCheckbox.getSelection(),
includeScreenshotCheckbox.getSelection(),
dartbugCheckbox.getSelection());
}
private void showData() {
try {
LogViewer logViewer = new LogViewer(getShell(), newFeedbackJob().getDataAsText());
logViewer.open();
} catch (Throwable th) {
MessageDialog.openError(
getParentShell(),
FeedbackMessages.FeedbackDialog_error_opening_log_label,
FeedbackMessages.FeedbackDialog_error_opening_log_detail);
}
}
private void showScreenshot() {
if (screenshot == null) {
MessageDialog.openError(
getParentShell(),
FeedbackMessages.FeedbackDialog_error_opening_screenshot_label,
FeedbackMessages.FeedbackDialog_error_opening_screenshot_detail);
}
try {
ScreenshotViewer screenshotViewer = new ScreenshotViewer(getShell(), screenshot);
screenshotViewer.open();
} catch (Throwable t) {
MessageDialog.openError(
getParentShell(),
FeedbackMessages.FeedbackDialog_error_opening_screenshot_label,
FeedbackMessages.FeedbackDialog_error_opening_screenshot_detail);
}
}
}