From 212099c0a18fba48167b1393e0c96bd56a548019 2010-09-08 19:11:33 From: Fernando Perez Date: 2010-09-08 19:11:33 Subject: [PATCH] Centralize Qt font selection into a generic utility. This makes a more flexible choice between main requested font and fallbacks, using a QFontInfo object that knows about the local platform. Use 'Consolas' on Win32 and Linux if available, fall back to respective native fonts otherwise. --- diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py index 1d11959..14c6822 100644 --- a/IPython/frontend/qt/console/console_widget.py +++ b/IPython/frontend/qt/console/console_widget.py @@ -1,3 +1,9 @@ +"""A base class for console-type widgets. +""" +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + # Standard library imports from os.path import commonprefix import re @@ -9,11 +15,14 @@ from PyQt4 import QtCore, QtGui # Local imports from IPython.config.configurable import Configurable -from IPython.frontend.qt.util import MetaQObjectHasTraits +from IPython.frontend.qt.util import MetaQObjectHasTraits, get_font from IPython.utils.traitlets import Bool, Enum, Int from ansi_code_processor import QtAnsiCodeProcessor from completion_widget import CompletionWidget +#----------------------------------------------------------------------------- +# Classes +#----------------------------------------------------------------------------- class ConsoleWidget(Configurable, QtGui.QWidget): """ An abstract base class for console-type widgets. This class has @@ -441,16 +450,19 @@ class ConsoleWidget(Configurable, QtGui.QWidget): def reset_font(self): """ Sets the font to the default fixed-width font for this platform. """ - font = QtGui.QFont() if sys.platform == 'win32': - # Prefer Consolas, but fall back to Courier if necessary. - font.setFamily('Consolas') - if not font.exactMatch(): - font.setFamily('Courier') + # Consolas ships with Vista/Win7, fallback to Courier if needed + family, fallback = 'Consolas', 'Courier' elif sys.platform == 'darwin': - font.setFamily('Monaco') + # OSX always has Monaco, no need for a fallback + family, fallback = 'Monaco', None else: - font.setFamily('Monospace') + # Consolas isn't too common on linux, but anyone who has it + # installed it because they want it for their monospaced apps, + # since it's better than anything on linux by default. + family, fallback = 'Consolas', 'Monospace' + + font = get_font(family, fallback) font.setPointSize(QtGui.qApp.font().pointSize()) font.setStyleHint(QtGui.QFont.TypeWriter) self._set_font(font) diff --git a/IPython/frontend/qt/util.py b/IPython/frontend/qt/util.py index 3ea578b..1191d29 100644 --- a/IPython/frontend/qt/util.py +++ b/IPython/frontend/qt/util.py @@ -2,7 +2,7 @@ """ # System library imports. -from PyQt4 import QtCore +from PyQt4 import QtCore, QtGui # IPython imports. from IPython.utils.traitlets import HasTraits @@ -23,3 +23,30 @@ class MetaQObjectHasTraits(MetaQObject, MetaHasTraits): QObject. See QtKernelManager for an example. """ pass + + +def get_font(family, fallback=None): + """Return a font of the requested family, using fallback as alternative. + + If a fallback is provided, it is used in case the requested family isn't + found. If no fallback is given, no alternative is chosen and Qt's internal + algorithms may automatically choose a fallback font. + + Parameters + ---------- + family : str + A font name. + fallback : str + A font name. + + Returns + ------- + font : QFont object + """ + font = QtGui.QFont(family) + # Check whether we got what we wanted using QFontInfo, since exactMatch() + # is overly strict and returns false in too many cases. + font_info = QtGui.QFontInfo(font) + if fallback is not None and font_info.family() != family: + font = QtGui.QFont(fallback) + return font