/******************************************************************************
* Copyright (C) 2013 André Berg and others
*
* 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:
* André Berg <andre.bergmedia@googlemail.com> - initial API and implementation
* Fabio Zadrozny <fabiofz@gmail.com> - ongoing maintenance
******************************************************************************/
package org.python.pydev.editor.saveactions;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.python.pydev.core.SystemUtils;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.PyEdit;
import org.python.pydev.editor.preferences.PyScopedPreferences;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.shared_ui.field_editors.LabelFieldEditor;
import org.python.pydev.shared_ui.field_editors.LinkFieldEditor;
import org.python.pydev.shared_ui.field_editors.ScopedFieldEditorPreferencePage;
import org.python.pydev.shared_ui.field_editors.ScopedPreferencesFieldEditor;
import org.python.pydev.shared_ui.tooltips.presenter.AbstractTooltipInformationPresenter;
import org.python.pydev.shared_ui.tooltips.presenter.ToolTipPresenterHandler;
/**
* Preference page for Pydev editor {@code Save Actions}.
* Save actions are actions performed on file buffers whenever
* a file resource is saved.
*
* @author André Berg
* @version 0.1
*/
public class PydevSaveActionsPrefPage extends ScopedFieldEditorPreferencePage implements IWorkbenchPreferencePage {
private class PydevSaveActionsPageLinkListener implements SelectionListener {
public PydevSaveActionsPageLinkListener() {
}
@Override
public void widgetSelected(SelectionEvent e) {
try {
URL url = new URL("http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html");
SystemUtils.openWebpageInEclipse(url, "SimpleDateFormat Java Docs");
} catch (MalformedURLException e1) {
Log.log(e1);
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
}
private StringFieldEditor dateFormatEditor;
private PydevDateFieldNameEditor fieldNameEditor;
private BooleanFieldEditor enableDateFieldActionEditor;
private LinkFieldEditor dateFormatHelpLinkEditor;
private static final String enableDateFieldActionEditorTooltipFormat = "" +
"Parses the file being saved for a module level\n" +
"field with name and value as defined by the custom\n" +
"name and date format below and updates it to the\n" +
"current date.";
private ToolTipPresenterHandler tooltipPresenter;
private BooleanFieldEditor sortImportsOnSave;
public PydevSaveActionsPrefPage() {
super(GRID);
final IPreferenceStore store = PydevPlugin.getDefault().getPreferenceStore();
setDescription("Save actions are run whenever a file is saved.\n");
setPreferenceStore(store);
}
public static final String SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES = "SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES";
public static final boolean DEFAULT_SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES = true;
public static final String FORMAT_BEFORE_SAVING = "FORMAT_BEFORE_SAVING";
public static final boolean DEFAULT_FORMAT_BEFORE_SAVING = false;
public static final String ENABLE_DATE_FIELD_ACTION = "ENABLE_DATE_FIELD_ACTION";
public static final boolean DEFAULT_ENABLE_DATE_FIELD_ACTION = false;
public static final String DATE_FIELD_FORMAT = "DATE_FIELD_FORMAT";
public static final String DEFAULT_DATE_FIELD_FORMAT = "yyyy-MM-dd";
public static final String DATE_FIELD_NAME = "DATE_FIELD_NAME";
public static final String DEFAULT_DATE_FIELD_NAME = "__updated__";
public static final String SORT_IMPORTS_ON_SAVE = "SORT_IMPORTS_ON_SAVE";
public static final boolean DEFAULT_SORT_IMPORTS_ON_SAVE = false;
@Override
protected void createFieldEditors() {
IInformationPresenter presenter = new AbstractTooltipInformationPresenter() {
@Override
protected void onUpdatePresentation(String hoverInfo, TextPresentation presentation) {
}
@Override
protected void onHandleClick(Object data) {
}
};
final Composite p = getFieldEditorParent();
addField(new BooleanFieldEditor(SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES,
"Apply save actions only to files in the workspace?", p));
addField(new BooleanFieldEditor(FORMAT_BEFORE_SAVING, "Auto-format editor contents before saving?", p));
addField(new LinkFieldEditor("link_formatpreferences", "Note: config in <a>code formatting preferences</a>", p,
new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String id = "org.python.pydev.plugin.pyCodeFormatterPage";
IWorkbenchPreferenceContainer workbenchPreferenceContainer = ((IWorkbenchPreferenceContainer) getContainer());
workbenchPreferenceContainer.openPage(id, null);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
}));
// Sort imports when file is saved?
sortImportsOnSave =
new BooleanFieldEditor(SORT_IMPORTS_ON_SAVE, "Sort imports on save?", p);
addField(sortImportsOnSave);
addField(new LinkFieldEditor("link_importpreferences",
"Note: config in <a>code style: imports preferences</a>", p,
new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String id = "org.python.pydev.ui.importsconf.ImportsPreferencesPage";
IWorkbenchPreferenceContainer workbenchPreferenceContainer = ((IWorkbenchPreferenceContainer) getContainer());
workbenchPreferenceContainer.openPage(id, null);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
}));
tooltipPresenter = new ToolTipPresenterHandler(p.getShell(), presenter,
"Tip: Click link to open SimpleDateFormat Java docs online.");
// Enable date field action editor (boolean)
IPreferenceStore prefStore = getPreferenceStore();
final String fieldName = prefStore.getString(DATE_FIELD_NAME);
final String enableDateFieldActionEditorTooltip =
String.format(enableDateFieldActionEditorTooltipFormat, fieldName);
enableDateFieldActionEditor =
new BooleanFieldEditor(ENABLE_DATE_FIELD_ACTION, "Update date field?", p);
enableDateFieldActionEditor.getDescriptionControl(p).setToolTipText(enableDateFieldActionEditorTooltip);
addField(enableDateFieldActionEditor);
// Date field name editor (string)
fieldNameEditor = new PydevDateFieldNameEditor(DATE_FIELD_NAME, "Date field name:",
PydevDateFieldNameEditor.UNLIMITED, p);
fieldNameEditor.getTextControl(p).setToolTipText(String.format("Default is %s", DEFAULT_DATE_FIELD_NAME));
fieldNameEditor.setEmptyStringAllowed(false);
//fieldNameEditor.setValidateStrategy(PydevDateFieldNameEditor.VALIDATE_ON_FOCUS_LOST);
fieldNameEditor.setEnabled(prefStore.getBoolean(ENABLE_DATE_FIELD_ACTION), p);
addField(fieldNameEditor);
// Date format editor (string)
dateFormatEditor = new StringFieldEditor(DATE_FIELD_FORMAT, "Date field format:", StringFieldEditor.UNLIMITED,
p);
dateFormatEditor.getTextControl(p).setToolTipText("Uses Java's SimpleDateFormat tokens.");
dateFormatEditor.setEmptyStringAllowed(false);
//dateFormatEditor.setValidateStrategy(StringFieldEditor.VALIDATE_ON_FOCUS_LOST);
dateFormatEditor.setEnabled(prefStore.getBoolean(ENABLE_DATE_FIELD_ACTION), p);
addField(dateFormatEditor);
// Token help editor (link)
final String dateFormatHelpLinkTooltip = "" +
"All tokens from Java's SimpleDateFormat class\n" +
"are supported. The most common ones are:\n" +
"\n" +
"y\t\tYear\n" +
"M\t\tMonth in year\n" +
"d\t\tDay in month\n" +
"E\t\tDay name in week\n" +
"H\t\tHour in day (0-23)\n" +
"h\t\tHour in am/pm (1-12)\n" +
"m\t\tMinute in hour\n" +
"s\t\tSecond in minute\n" +
"\n" +
"Enclose literal characters in single quotes.";
dateFormatHelpLinkEditor =
new LinkFieldEditor("link_dateFormat", "<a>Supported tokens</a>", p,
new PydevSaveActionsPrefPage.PydevSaveActionsPageLinkListener(),
dateFormatHelpLinkTooltip, tooltipPresenter);
addField(dateFormatHelpLinkEditor);
addField(new LabelFieldEditor("__dummy__",
"I.e.: __updated__=\"2010-01-01\" will be synched on save.", p));
addField(new ScopedPreferencesFieldEditor(p, PydevPlugin.DEFAULT_PYDEV_SCOPE, this));
}
@Override
public void init(IWorkbench workbench) {
}
public static boolean getDateFieldActionEnabled(PyEdit pyEdit) {
return PyScopedPreferences.getBoolean(ENABLE_DATE_FIELD_ACTION, pyEdit);
}
public static boolean getSortImportsOnSave(PyEdit pyEdit) {
return PyScopedPreferences.getBoolean(SORT_IMPORTS_ON_SAVE, pyEdit);
}
public static boolean getFormatBeforeSaving(PyEdit pyEdit) {
return PyScopedPreferences.getBoolean(FORMAT_BEFORE_SAVING, pyEdit);
}
public static String getDateFieldName(PyEdit pyEdit) {
return PyScopedPreferences.getString(DATE_FIELD_NAME, pyEdit, DEFAULT_DATE_FIELD_NAME);
}
public static String getDateFieldFormat(PyEdit pyEdit) {
return PyScopedPreferences.getString(DATE_FIELD_FORMAT, pyEdit, DEFAULT_DATE_FIELD_FORMAT);
}
public static boolean getAutoformatOnlyWorkspaceFiles(IAdaptable projectAdaptable) {
return PyScopedPreferences.getBoolean(SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES, projectAdaptable);
}
@Override
protected void performDefaults() {
super.performDefaults();
updateDateFieldStringEditorState();
}
private void updateDateFieldStringEditorState() {
final boolean val = enableDateFieldActionEditor.getBooleanValue();
final Composite p = getFieldEditorParent();
dateFormatEditor.setEnabled(val, p);
fieldNameEditor.setEnabled(val, p);
}
@Override
public void propertyChange(PropertyChangeEvent event) {
super.propertyChange(event);
if (enableDateFieldActionEditor.equals(event.getSource())) {
updateDateFieldStringEditorState();
}
setValid((dateFormatEditor.isValid() && fieldNameEditor.isValid()));
updatePageButtons();
}
private void updatePageButtons() {
final boolean valid = isValid();
final Button defaultButton = getShell().getDefaultButton();
if (!valid) {
getApplyButton().setEnabled(false);
if (defaultButton != null) {
defaultButton.setEnabled(false);
}
} else {
getApplyButton().setEnabled(true);
if (defaultButton != null) {
defaultButton.setEnabled(true);
}
}
}
}