/*
* 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.engine.utilities.instrumentation.HealthUtils;
import com.google.dart.tools.core.DartCoreDebug;
import com.google.dart.tools.ui.internal.util.ExternalBrowserUtil;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* An action to open the {@link FeedbackDialog}.
* <p>
* TODO list
* <li>Currently the screenshot capture doesn't work on the MacOS- dartbug.com/6458
* <li>Currently the text and jpeg image are sent as separate requests by
* {@link FeedbackSubmissionJob}, it would be awesome if we sent them all together so that we could
* have a single email with attachments, and be smarter about how the information is put together as
* it is sent out by the AppEngine server
*
* @see FeedbackSubmissionJob
*/
public class OpenFeedbackDialogAction extends Action implements IShellProvider {
private static final String FEEDBACK_URL = "https://github.com/dart-lang/eclipse3/issues";
private IShellProvider shellProvider;
//the dialog shell, cached in case we want to ensure there is only one
private Shell dialogShell;
private final String productName;
public OpenFeedbackDialogAction(IShellProvider shellProvider, String productName) {
this.productName = productName;
setShellProvider(shellProvider);
}
public OpenFeedbackDialogAction(String productName) {
this(null, productName);
}
/**
* Get the active dialog shell (if there is one); may be <code>null</code>.
*/
public Shell getDialogShell() {
return dialogShell;
}
@Override
public Shell getShell() {
return shellProvider.getShell();
}
@Override
public void run() {
if (FEEDBACK_URL != null) {
ExternalBrowserUtil.openInExternalBrowser(FEEDBACK_URL);
return;
}
HealthUtils.ReportHealth("FeedbackDialog.ctor");
Image screenshot = captureScreen();
if (DartCoreDebug.ENABLE_NEW_FEEDBACK) {
try {
new FeedbackDialog2(null, productName, screenshot) {
@Override
public void create() {
super.create();
//cache that the dialog is open
dialogShell = getShell();
}
@Override
public int open() {
int result = SWT.CANCEL;
try {
result = super.open();
} finally {
//cache that the dialog is closed
dialogShell = null;
}
return result;
}
}.open();
} finally {
if (screenshot != null) {
screenshot.dispose();
}
}
} else {
new FeedbackDialog(getShell(), productName, screenshot) {
@Override
public void create() {
super.create();
//cache that the dialog is open
dialogShell = getShell();
}
@Override
public int open() {
int result = SWT.CANCEL;
try {
result = super.open();
} finally {
//cache that the dialog is closed
dialogShell = null;
}
return result;
}
}.open();
}
}
/**
* @param shellProvider the shellProvider to set
*/
public void setShellProvider(IShellProvider shellProvider) {
this.shellProvider = shellProvider;
}
/**
* Creates screen shot of entire Dart Editor.
*
* @return the created screen capture
*/
private Image captureScreen() {
GC gc = null;
try {
Shell shell = getShell();
shell.redraw();
shell.update();
final Rectangle shellBounds = shell.getBounds();
final Display standardDisplay = getShell().getDisplay();
standardDisplay.update();
Image image = new Image(standardDisplay, shellBounds.width, shellBounds.height);
gc = new GC(standardDisplay);
gc.copyArea(image, shellBounds.x, shellBounds.y);
return image;
} catch (Throwable ex) {
return null;
} finally {
if (gc != null) {
gc.dispose();
}
}
}
}