package org.python.pydev.plugin.preferences; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; 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.Label; import org.eclipse.swt.widgets.Shell; import org.osgi.service.prefs.BackingStoreException; import org.python.pydev.core.log.Log; import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.shared_ui.dialogs.DialogMemento; import org.python.pydev.shared_ui.utils.RunInUiThread; /** * @author fabioz */ public class CheckDefaultPreferencesDialog extends TrayDialog { private Button okButton; private Button cancelButton; private DialogMemento memento; private final CheckInfo[] missing; List<Button> checkBoxes; CheckDefaultPreferencesDialog(Shell shell, CheckInfo[] missing) { super(shell); setHelpAvailable(false); setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.MAX | SWT.RESIZE | getDefaultOrientation()); setBlockOnOpen(true); memento = new DialogMemento(shell, "org.python.pydev.plugin.preferences.CheckDefaultPreferencesDialog"); this.missing = missing; checkBoxes = new ArrayList<>(missing.length + 2); } @Override protected void createButtonsForButtonBar(Composite parent) { okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); cancelButton = createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } @Override public boolean close() { memento.writeSettings(getShell()); return super.close(); } @Override protected Point getInitialSize() { return memento.getInitialSize(super.getInitialSize(), getShell()); } @Override protected Point getInitialLocation(Point initialSize) { return memento.getInitialLocation(initialSize, super.getInitialLocation(initialSize), getShell()); } @Override protected Control createDialogArea(Composite parent) { memento.readSettings(); Composite area = (Composite) super.createDialogArea(parent); createLabel(area, "Uncheck settings that should not be changed.\n"); for (CheckInfo c : this.missing) { Button bt = addCheckBox(area, c.msg, c.description); bt.setData(c); } createLabel(area, "\n"); //Just add spacing Button bt = addCheckBox(area, "Re-check whenever a PyDev editor is opened?", ""); bt.setSelection(PydevRootPrefs.getCheckPreferredPydevSettings()); bt.setData(PydevRootPrefs.CHECK_PREFERRED_PYDEV_SETTINGS); return area; } private void createLabel(Composite area, String text) { Label label = new Label(area, SWT.NONE); label.setText(text); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.grabExcessHorizontalSpace = true; label.setLayoutData(data); } private Button addCheckBox(Composite area, String msg, String desc) { Button bt = new Button(area, SWT.CHECK); bt.setText(msg); bt.setSelection(true); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.grabExcessHorizontalSpace = true; bt.setLayoutData(data); checkBoxes.add(bt); if (desc.length() > 0) { Label label = new Label(area, SWT.NONE); label.setText(desc); data = new GridData(GridData.FILL_HORIZONTAL); data.grabExcessHorizontalSpace = true; label.setLayoutData(data); } return bt; } @Override protected boolean isResizable() { return true; } @Override protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText("Default Eclipse preferences for PyDev"); } @Override protected void okPressed() { applyChanges(); super.okPressed(); } public static class CheckInfo { public final String description; public final String plugin; public final String pref; public final String value; public final String msg; private CheckInfo(String plugin, String pref, String value, String msg, String description) { this.plugin = plugin; this.pref = pref; this.value = value; this.msg = msg; this.description = description; } public static CheckInfo[] getMissing() { String buildDesc = "\tReason: To launch a file in PyDev a build is not required.\n\n" + "\tNote that JDT/CDT may require a build to compile before launching,\n" + "\tso, leave it unchecked if you use one of those plugins and want to\n" + "\tautomatically build before launching."; CheckInfo[] infos = new CheckInfo[] { new CheckInfo("org.eclipse.debug.ui", "org.eclipse.debug.ui.wait_for_build", "never", "Wait for ongoing build before launching: never", buildDesc), new CheckInfo( "org.eclipse.debug.ui", "org.eclipse.debug.ui.build_before_launch", "false", "Build (if required) before launching: no", buildDesc), new CheckInfo( "org.eclipse.debug.ui", "org.eclipse.debug.ui.UseContextualLaunch", "", "Launch operation: always launch the previously selected application.", "\tReason: On PyDev, F9 launches the current selection (and Ctrl+F9 launches unit-tests),\n" + "\tso it's recommended that Ctrl+F11 is set to re-launch the last launch and\n" + "\tF11 to debug the last launch.") }; ArrayList<CheckInfo> lst = new ArrayList<>(infos.length); for (CheckInfo c : infos) { IEclipsePreferences node = InstanceScope.INSTANCE.getNode(c.plugin); if (!c.value.equals(node.get(c.pref, ""))) { lst.add(c); } } return lst.toArray(new CheckInfo[lst.size()]); } public void apply() { IEclipsePreferences node = InstanceScope.INSTANCE.getNode(this.plugin); node.put(this.pref, this.value); try { node.flush(); } catch (BackingStoreException e) { Log.log(e); } } } private void applyChanges() { for (Button bt : checkBoxes) { Object data = bt.getData(); if (data instanceof CheckInfo) { if (bt.getSelection()) { CheckInfo checkInfo = (CheckInfo) data; checkInfo.apply(); } } else if (data.equals(PydevRootPrefs.CHECK_PREFERRED_PYDEV_SETTINGS)) { PydevRootPrefs.setCheckPreferredPydevSettings(bt.getSelection()); } else { Log.log("Unexpected data: " + data); } } } public static volatile boolean showing = false; public static void askAboutSettings() { IPreferenceStore preferenceStore = PydevPlugin.getDefault().getPreferenceStore(); boolean checkPreferredSettings = preferenceStore.getBoolean(PydevRootPrefs.CHECK_PREFERRED_PYDEV_SETTINGS); if (checkPreferredSettings) { final CheckInfo[] missing = CheckInfo.getMissing(); if (missing.length == 0) { return; } boolean runNowIfInUiThread = false; RunInUiThread.async(new Runnable() { @Override public void run() { if (showing) { return; } Display disp = Display.getCurrent(); Shell shell = disp.getActiveShell(); if (shell == null) { shell = new Shell(disp); } CheckDefaultPreferencesDialog dialog = new CheckDefaultPreferencesDialog(shell, missing); showing = true; try { dialog.open(); } finally { showing = false; } } }, runNowIfInUiThread); } } }