diff --git a/plugins/org.python.pydev.core/src/org/python/pydev/core/FontUtils.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/FontUtils.java
index 12d894d71..216da9352 100644
--- a/plugins/org.python.pydev.core/src/org/python/pydev/core/FontUtils.java
+++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/FontUtils.java
@@ -1,103 +1,129 @@
-/**
- * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
- * Licensed under the terms of the Eclipse Public License (EPL).
- * Please see the license.txt included with this distribution for details.
- * Any modifications to this file must keep this entire header intact.
- */
-package org.python.pydev.core;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.osgi.service.environment.Constants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.FontData;
-
-import com.aptana.shared_core.structure.Tuple;
-
-/**
- *
FontUtils provides helper methods dealing with
- * Fonts.
- *
- * @author André Berg
- * @version 0.1
- */
-public class FontUtils {
-
- /**
- * Selects a proper font name and height for various usage cases of monospaced fonts throughout Pydev.
- *
- * @param usage intended usage. See {@link IFontUsage} for valid values.
- * @return a {@link Tuple} containing the font name as {@link String} and the base height as {@link Integer}.
- * @throws IllegalArgumentException if usage is not found in {@link IFontUsage}.
- */
- private static Tuple getCodeFontNameAndHeight(int usage) throws IllegalArgumentException {
- String fontName = "Courier New";
- int fontHeight = 10;
- if (Platform.getOS().equals(Constants.OS_MACOSX)) {
- switch (usage) {
- case IFontUsage.STYLED:
- fontName = "Monaco";
- fontHeight = 11;
- break;
- case IFontUsage.DIALOG:
- // on OS X we need a different font because
- // under Mac SWT the bitmap font rasterizer
- // doesn't take hinting into account and thus
- // makes small fonts rendered as bitmaps unreadable
- // see http://aptanastudio.tenderapp.com/discussions/problems/2052-some-dialogs-have-unreadable-small-font-size
- fontName = "Courier";
- fontHeight = 11;
- break;
- case IFontUsage.WIDGET:
- fontName = "Monaco";
- fontHeight = 9;
- break;
- case IFontUsage.IMAGECACHE:
- fontName = "Monaco";
- fontHeight = 11;
- break;
-
- default:
- throw new IllegalArgumentException(
- "Invalid usage. See org.python.pydev.core.IFontUsage for valid values.");
- }
- } else {
- switch (usage) {
- case IFontUsage.STYLED:
- fontName = "Courier New";
- fontHeight = 10;
- break;
- case IFontUsage.DIALOG:
- fontName = "Courier New";
- fontHeight = 8;
- break;
- case IFontUsage.WIDGET:
- fontName = "Courier New";
- fontHeight = 10;
- break;
- case IFontUsage.IMAGECACHE:
- fontName = "Courier New";
- fontHeight = 9;
- break;
-
- default:
- throw new IllegalArgumentException(
- "Invalid usage. See org.python.pydev.core.IFontUsage for valid values.");
- }
- }
- return new Tuple(fontName, fontHeight);
- }
-
- public static FontData getFontData(int usage, boolean useDefaultJFaceFontIfPossible) {
- if (useDefaultJFaceFontIfPossible) {
- FontData[] textFontData = JFaceResources.getTextFont().getFontData();
- if (textFontData.length == 1) {
- return textFontData[0];
- }
- }
- Tuple codeFontDetails = FontUtils.getCodeFontNameAndHeight(IFontUsage.IMAGECACHE);
- String fontName = codeFontDetails.o1;
- int base = codeFontDetails.o2.intValue();
- return new FontData(fontName, base, SWT.BOLD);
- }
-}
+/**
+ * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
+ * Licensed under the terms of the Eclipse Public License (EPL).
+ * Please see the license.txt included with this distribution for details.
+ * Any modifications to this file must keep this entire header intact.
+ */
+package org.python.pydev.core;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.osgi.service.environment.Constants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.FontData;
+
+import com.aptana.shared_core.structure.Tuple;
+
+/**
+ * FontUtils provides helper methods dealing with
+ * Fonts.
+ *
+ * @author André Berg
+ * @version 0.2
+ */
+public class FontUtils {
+
+ /**
+ * Selects a proper font name and height for various usage cases of monospaced fonts throughout Pydev.
+ *
+ * @param usage intended usage. See {@link IFontUsage} for valid values.
+ * @return a {@link Tuple} containing the font name as {@link String} and the base height as {@link Integer}.
+ * @throws IllegalArgumentException if usage is not found in {@link IFontUsage}.
+ */
+ private static Tuple getCodeFontNameAndHeight(int usage) throws IllegalArgumentException {
+ String fontName = "Courier New";
+ int fontHeight = 10;
+ if (Platform.getOS().equals(Constants.OS_MACOSX)) {
+ switch (usage) {
+ case IFontUsage.STYLED:
+ fontName = "Monaco";
+ fontHeight = 11;
+ break;
+ case IFontUsage.DIALOG:
+ // on OS X we need a different font because
+ // under Mac SWT the bitmap font rasterizer
+ // doesn't take hinting into account and thus
+ // makes small fonts rendered as bitmaps unreadable
+ // see http://aptanastudio.tenderapp.com/discussions/problems/2052-some-dialogs-have-unreadable-small-font-size
+ fontName = "Courier";
+ fontHeight = 11;
+ break;
+ case IFontUsage.WIDGET:
+ fontName = "Monaco";
+ fontHeight = 9;
+ break;
+ case IFontUsage.IMAGECACHE:
+ fontName = "Monaco";
+ fontHeight = 11;
+ break;
+ case IFontUsage.SMALLUI:
+ fontName = "Monaco";
+ fontHeight = 9;
+ break;
+
+ default:
+ throw new IllegalArgumentException(
+ "Invalid usage. See org.python.pydev.core.IFontUsage for valid values.");
+ }
+ } else {
+ switch (usage) {
+ case IFontUsage.STYLED:
+ fontName = "Courier New";
+ fontHeight = 10;
+ break;
+ case IFontUsage.DIALOG:
+ fontName = "Courier New";
+ fontHeight = 8;
+ break;
+ case IFontUsage.WIDGET:
+ fontName = "Courier New";
+ fontHeight = 10;
+ break;
+ case IFontUsage.IMAGECACHE:
+ fontName = "Courier New";
+ fontHeight = 9;
+ break;
+ case IFontUsage.SMALLUI:
+ fontName = "Courier New";
+ fontHeight = 8;
+ break;
+
+ default:
+ throw new IllegalArgumentException(
+ "Invalid usage. See org.python.pydev.core.IFontUsage for valid values.");
+ }
+ }
+ return new Tuple(fontName, fontHeight);
+ }
+
+
+ /**
+ * Calls {@link #getFontData(int, boolean)} with {@link SWT#NONE} for the style param.
+ * @see {@link #getFontData(int, int, boolean)}
+ */
+ public static FontData getFontData(int usage, boolean useDefaultJFaceFontIfPossible) {
+ return getFontData(usage, SWT.NONE, useDefaultJFaceFontIfPossible);
+ }
+
+ /**
+ * Select a monospaced font based on intended usage.
+ * Can be used to provide a consistend code font size between platforms.
+ *
+ * @param usage intended usage. See {@link IFontUsage} for valid values.
+ * @param style SWT style constants mask
+ * @param useDefaultJFaceFontIfPossible
+ * @return {@link FontData} object
+ */
+ public static FontData getFontData(int usage, int style, boolean useDefaultJFaceFontIfPossible) {
+ if (useDefaultJFaceFontIfPossible) {
+ FontData[] textFontData = JFaceResources.getTextFont().getFontData();
+ if (textFontData.length == 1) {
+ return textFontData[0];
+ }
+ }
+ Tuple codeFontDetails = FontUtils.getCodeFontNameAndHeight(usage);
+ String fontName = codeFontDetails.o1;
+ int base = codeFontDetails.o2.intValue();
+ return new FontData(fontName, base, style);
+ }
+}
diff --git a/plugins/org.python.pydev.core/src/org/python/pydev/core/IFontUsage.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/IFontUsage.java
index 1de25c30d..7fd1c9af1 100644
--- a/plugins/org.python.pydev.core/src/org/python/pydev/core/IFontUsage.java
+++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/IFontUsage.java
@@ -1,46 +1,51 @@
-/**
- * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
- * Licensed under the terms of the Eclipse Public License (EPL).
- * Please see the license.txt included with this distribution for details.
- * Any modifications to this file must keep this entire header intact.
- */
-package org.python.pydev.core;
-
-/**
- * IFontUsage is an enum-like interface describing usage cases
- * for fonts used throughout Pydev.
- *
- * It is used primarily by {@link FontUtils} to have all font usages
- * in a central place to ease future edits.
- *
- *
- *
- * value | used for |
- * STYLED | styled text widgets (ex. Editor prefs) |
- * DIALOG | modal dialogs (ex. Py2To3) |
- * WIDGET | other widgets (ex. Code Coverage view or Comment Blocks prefs) |
- * IMAGECACHE | overlaying monospaced text onto images |
- *
- *
- *
- * @author André Berg
- * @version 0.1
- */
-public interface IFontUsage {
- /**
- * used for styled text widgets (ex. Editor prefs)
- */
- public static final int STYLED = 0;
- /**
- * used for modal dialogs (ex. Py2To3 dialog)
- */
- public static final int DIALOG = 1;
- /**
- * used for other widgets (ex. Code Coverage view or Comment Blocks prefs)
- */
- public static final int WIDGET = 2;
- /**
- * used in {@link org.python.pydev.core.bundle.ImageCache ImageCache} for overlaying code text onto images
- */
- public static final int IMAGECACHE = 3;
-}
+/**
+ * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
+ * Licensed under the terms of the Eclipse Public License (EPL).
+ * Please see the license.txt included with this distribution for details.
+ * Any modifications to this file must keep this entire header intact.
+ */
+package org.python.pydev.core;
+
+/**
+ * IFontUsage is an enum-like interface describing usage cases
+ * for fonts used throughout Pydev.
+ *
+ * It is used primarily by {@link FontUtils} to have all font usages
+ * in a central place to ease future edits.
+ *
+ *
+ *
+ * value | used for |
+ * STYLED | styled text widgets (ex. Editor prefs) |
+ * DIALOG | modal dialogs (ex. Py2To3) |
+ * WIDGET | other widgets (ex. Code Coverage view or Comment Blocks prefs) |
+ * IMAGECACHE | overlaying monospaced text onto images |
+ * SMALLUI | for UI layouts where space is at a premium |
+ *
+ *
+ *
+ * @author André Berg
+ * @version 0.2
+ */
+public interface IFontUsage {
+ /**
+ * used for styled text widgets (ex. Editor prefs)
+ */
+ public static final int STYLED = 0;
+ /**
+ * used for modal dialogs (ex. Py2To3 dialog)
+ */
+ public static final int DIALOG = 1;
+ /**
+ * used for other widgets (ex. Code Coverage view or Comment Blocks prefs)
+ */
+ public static final int WIDGET = 2;
+ /**
+ * used in {@link org.python.pydev.core.bundle.ImageCache ImageCache} for overlaying code text onto images
+ */
+ public static final int IMAGECACHE = 3;
+ /**
+ * used for UI layouts where space is at a premium
+ */
+ public static final int SMALLUI = 4;
+}
diff --git a/plugins/org.python.pydev.core/src/org/python/pydev/core/SystemUtils.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/SystemUtils.java
new file mode 100644
index 000000000..c435cc47f
--- /dev/null
+++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/SystemUtils.java
@@ -0,0 +1,62 @@
+package org.python.pydev.core;
+
+import java.awt.Desktop;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.browser.IWebBrowser;
+import org.python.pydev.core.log.Log;
+
+/**
+ * Utils operating system functionality.
+ *
+ * @author André Berg
+ * @version 0.1
+ */
+public class SystemUtils {
+
+ /**
+ * Open webpage given by URI with the default system browser.
+ */
+ public static void openWebpage(URI uri) {
+ Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
+ if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
+ try {
+ desktop.browse(uri);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Open webpage given by URL with the default system browser.
+ */
+ public static void openWebpage(URL url) {
+ try {
+ openWebpage(url.toURI());
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Open a webpage in Eclipse's default browser.
+ *
+ * @param url URL address of the webpage
+ * @param id String id for the newly created browser view
+ */
+ public static void openWebpageInEclipse(URL url, String id) {
+ IWebBrowser browser;
+ try {
+ browser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser(id);
+ browser.openURL(url);
+ } catch (PartInitException e) {
+ Log.log(e);
+ }
+ }
+}
+
diff --git a/plugins/org.python.pydev.red_core/src/org/python/pydev/red_core/AddRedCorePreferences.java b/plugins/org.python.pydev.red_core/src/org/python/pydev/red_core/AddRedCorePreferences.java
index a39e2f5d2..bd4a0480a 100644
--- a/plugins/org.python.pydev.red_core/src/org/python/pydev/red_core/AddRedCorePreferences.java
+++ b/plugins/org.python.pydev.red_core/src/org/python/pydev/red_core/AddRedCorePreferences.java
@@ -26,6 +26,8 @@
import org.python.pydev.red_core.preferences.PydevRedCorePreferencesInitializer;
import org.python.pydev.utils.LabelFieldEditor;
import org.python.pydev.utils.LinkFieldEditor;
+import org.python.pydev.core.FontUtils;
+import org.python.pydev.core.IFontUsage;
import com.aptana.editor.common.CommonEditorPlugin;
import com.aptana.theme.IThemeManager;
@@ -225,7 +227,7 @@ public void widgetDefaultSelected(SelectionEvent e) {
"Prompt: console.prompt\n" + "", appearanceComposite);
Label labelControl = labelFieldEditor.getLabelControl(appearanceComposite);
try {
- FontData labelFontData = new FontData("Courier New", 8, SWT.NONE);
+ FontData labelFontData = FontUtils.getFontData(IFontUsage.SMALLUI, false);
labelControl.setFont(new Font(labelControl.getDisplay(), labelFontData));
} catch (Throwable e) {
//ignore
diff --git a/plugins/org.python.pydev/plugin.xml b/plugins/org.python.pydev/plugin.xml
index 6c7f1e0b9..5d9636b28 100644
--- a/plugins/org.python.pydev/plugin.xml
+++ b/plugins/org.python.pydev/plugin.xml
@@ -364,6 +364,12 @@
id="org.python.pydev.editor.codefolding.PyDevCodeFoldingPrefPage"
name="Code Folding">
+
+
Supported tokens", p,
+ new PydevSaveActionsPrefPage.PydevSaveActionsPageLinkListener(),
+ dateFormatHelpLinkTooltip, tooltipPresenter);
+ addField(dateFormatHelpLinkEditor);
+
+ }
+
+ public void init(IWorkbench workbench) {
+ }
+
+ public static boolean getDateFieldActionEnabled() {
+ return PydevPrefs.getPreferences().getBoolean(ENABLE_DATE_FIELD_ACTION);
+ }
+
+ public static String getDateFieldName() {
+ final String fieldName = PydevPrefs.getPreferences().getString(DATE_FIELD_NAME);
+ if (fieldName.isEmpty()) {
+ return DEFAULT_DATE_FIELD_NAME;
+ }
+ return fieldName;
+ }
+
+ public static String getDateFieldFormat() {
+ final String fieldName = PydevPrefs.getPreferences().getString(DATE_FIELD_FORMAT);
+ if (fieldName.isEmpty()) {
+ return DEFAULT_DATE_FIELD_FORMAT;
+ }
+ return fieldName; }
+
+ protected void performDefaults() {
+ final Composite p = getFieldEditorParent();
+ enableDateFieldActionEditor.loadDefault();
+ dateFormatEditor.loadDefault();
+ fieldNameEditor.loadDefault();
+ dateFormatEditor.setEnabled(false, p);
+ fieldNameEditor.setEnabled(false, p);
+ super.updateApplyButton();
+ }
+
+ 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);
+ }
+ }
+ }
+}