/******************************************************************************
* Copyright (C) 2013 Fabio Zadrozny
*
* 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:
* Fabio Zadrozny <fabiofz@gmail.com> - initial API and implementation
******************************************************************************/
package org.python.pydev.editor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.python.pydev.plugin.preferences.PydevPrefs;
import org.python.pydev.shared_core.SharedCorePlugin;
import org.python.pydev.shared_core.string.WrapAndCaseUtils;
import org.python.pydev.shared_ui.UIConstants;
import org.python.pydev.shared_ui.utils.RunInUiThread;
final class DialogNotifier extends Dialog {
private static final int BOLD_COLS = 120;
public DialogNotifier(Shell shell) {
super(shell);
setShellStyle(
SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE | SWT.RESIZE | SWT.MAX | getDefaultOrientation());
setBlockOnOpen(true);
}
@Override
protected boolean isResizable() {
return true;
}
@Override
protected Point getInitialSize() {
return new Point(800, 600);
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
GridData gridData = null;
GridLayout layout = (GridLayout) composite.getLayout();
layout.numColumns = 1;
String msg = "Help keeping PyDev supported";
createLabel(composite, WrapAndCaseUtils.wrap(msg, BOLD_COLS), 1);
try {
final String html = "<html><head>"
+
"<base href=\"http://pydev.org\" >"
+
"<title>Keeping PyDev supported</title></head>"
+
"<body>"
+
"I'm reaching out for you today to ask for your help to keep PyDev properly supported."
+
"<br/>"
+
"<br/>"
+
"PyDev is kept as an open source product and relies on contributions to remain being developed, so, if you feel that's a worthy goal, please take a look at <a href=\"http://pydev.org\">http://pydev.org</a> and contribute if you can.<br/><br/>"
+
""
+
"Thank you,"
+
"<br/>"
+
"<br/>"
+
"Fabio"
+
"<br/>"
+
"<br/>"
+
"p.s.: Sorry for the dialog. It won't be shown again in this workspace after you click the \"Read it\" button."
+
"</body></html>";
ToolBar navBar = new ToolBar(composite, SWT.NONE);
//this is the place where it might fail
final Browser browser = new Browser(composite, SWT.BORDER);
browser.setText(html);
gridData = new GridData(GridData.FILL_BOTH);
browser.setLayoutData(gridData);
final ToolItem back = new ToolItem(navBar, SWT.PUSH);
back.setImage(org.python.pydev.plugin.PydevPlugin.getImageCache().get(UIConstants.BACK));
final ToolItem forward = new ToolItem(navBar, SWT.PUSH);
forward.setImage(org.python.pydev.plugin.PydevPlugin.getImageCache().get(UIConstants.FORWARD));
final ToolItem stop = new ToolItem(navBar, SWT.PUSH);
stop.setImage(org.python.pydev.plugin.PydevPlugin.getImageCache().get(UIConstants.STOP));
final ToolItem refresh = new ToolItem(navBar, SWT.PUSH);
refresh.setImage(org.python.pydev.plugin.PydevPlugin.getImageCache().get(UIConstants.REFRESH));
final ToolItem home = new ToolItem(navBar, SWT.PUSH);
home.setImage(org.python.pydev.plugin.PydevPlugin.getImageCache().get(UIConstants.HOME));
back.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
browser.back();
}
});
forward.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
browser.forward();
}
});
stop.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
browser.stop();
}
});
refresh.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
browser.refresh();
}
});
home.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
browser.setText(html);
}
});
} catch (Throwable e) {
//some error might happen creating it according to the docs, so, let's put another text into the widget
String msg2 = "I'm reaching out for you today to ask for your help to keep PyDev\n"
+ "properly supported.\n"
+
"\n"
+
"PyDev is kept as an open source product and relies on contributions\n"
+ "to remain being developed, so, if you feel that's a worthy goal, please\n"
+ "take a look at http://pydev.org and contribute if you can.\n"
+
"\n"
+
"Thank you,\n"
+
"\n"
+
"Fabio\n"
+
"\n"
+
"p.s.: Sorry for the dialog. It won't be shown again in this workspace after\n"
+ "you click the \"Read it\" button.\n"
+
"";
createText(composite, msg2, 1);
}
return composite;
}
public boolean doClose() {
return super.close();
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
// create OK and Cancel buttons by default
Button button = createButton(parent, IDialogConstants.OK_ID, " Show later ", true);
button.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
doClose();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
button = createButton(parent, IDialogConstants.CLIENT_ID, " Read it ", true);
button.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
doClose();
IPreferenceStore preferenceStore = PydevPrefs.getPreferenceStore();
//Show it again only after a full year has elapsed.
preferenceStore.setValue(PydevShowBrowserMessage.PYDEV_FUNDING_SHOW_AT_TIME,
System.currentTimeMillis() + (PydevShowBrowserMessage.ONE_DAY_IN_MILLIS * 365));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
/**
* @param composite
* @param labelMsg
* @return
*/
private Text createText(Composite composite, String labelMsg, int colSpan) {
Text text = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY);
GridData gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = colSpan;
text.setLayoutData(gridData);
text.setText(labelMsg);
return text;
}
/**
* @param composite
* @param labelMsg
* @return
*/
private Label createLabel(Composite composite, String labelMsg, int colSpan) {
Label label = new Label(composite, SWT.NONE);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = colSpan;
label.setLayoutData(gridData);
label.setText(labelMsg);
return label;
}
}
public class PydevShowBrowserMessage {
public static final String PYDEV_FUNDING_SHOW_AT_TIME = "PYDEV_FUNDING_SHOW_AT_TIME_2016";
private static boolean shownInSession = false;
public static final long ONE_DAY_IN_MILLIS = 86400000;
public static void show() {
if (shownInSession) {
return;
}
shownInSession = true;
if (SharedCorePlugin.inTestMode()) {
return;
}
String hide = System.getProperty("pydev.funding.hide");
if (hide != null && (hide.equals("1") || hide.equals("true"))) {
return;
}
IPreferenceStore preferenceStore = PydevPrefs.getPreferenceStore();
long showAtTime = preferenceStore.getLong(PYDEV_FUNDING_SHOW_AT_TIME);
boolean show;
if (showAtTime == 0) {
// It was never shown, so, show it after 3 days from now (we don't want to show
// the dialog as the first thing after the user installed it).
preferenceStore.setValue(PYDEV_FUNDING_SHOW_AT_TIME,
System.currentTimeMillis() + (ONE_DAY_IN_MILLIS * 3));
show = false;
} else if (System.currentTimeMillis() < showAtTime) {
// We still didn't reach the time for it to show.
show = false;
} else {
show = true;
}
if (show) {
boolean runNowIfInUiThread = false;
RunInUiThread.async(new Runnable() {
@Override
public void run() {
Display disp = Display.getCurrent();
Shell shell = disp.getActiveShell();
if (shell == null) {
shell = new Shell(disp);
}
DialogNotifier notifier = new DialogNotifier(shell);
notifier.open();
}
}, runNowIfInUiThread);
}
}
}