5
5
# (see spyderlib/__init__.py for details)
8
Spyder GUI-related configuration management
9
(for non-GUI configuration, see spyderlib/baseconfig.py)
8
Spyder configuration options
11
Important note regarding shortcuts:
12
For compatibility with QWERTZ keyboards, one must avoid using the following
14
Ctrl + Alt + Q, W, F, G, Y, X, C, V, B, N
10
Note: Leave this file free of Qt related imports, so that it can be used to
11
quickly load a user config file
19
16
import os.path as osp
21
from spyderlib.qt.QtGui import QLabel, QIcon, QPixmap, QFont, QFontDatabase
24
from spyderlib.userconfig import UserConfig, get_home_dir, NoDefault
25
from spyderlib.baseconfig import (SUBFOLDER, CHECK_ALL, EXCLUDED_NAMES,
26
get_module_data_path, _)
19
from spyderlib.userconfig import UserConfig, get_home_dir
20
from spyderlib.baseconfig import SUBFOLDER, CHECK_ALL, EXCLUDED_NAMES, _
27
21
from spyderlib.utils import iofuncs, codeanalysis
30
24
SANS_SERIF = ['Sans Serif', 'DejaVu Sans', 'Bitstream Vera Sans',
31
'Bitstream Charter', 'Times', 'Lucida Grande', 'Calibri',
32
'MS Shell Dlg 2', 'Verdana', 'Geneva', 'Lucid', 'Arial',
33
'Helvetica', 'Avant Garde', 'sans-serif']
25
'Bitstream Charter', 'Lucida Grande', 'MS Shell Dlg 2',
26
'Calibri', 'Verdana', 'Geneva', 'Lucid', 'Arial',
27
'Helvetica', 'Avant Garde', 'Times', 'sans-serif']
35
29
MONOSPACE = ['Monospace', 'DejaVu Sans Mono', 'Consolas', 'Monaco',
36
30
'Bitstream Vera Sans Mono', 'Andale Mono', 'Liberation Mono',
55
49
(_("C++ files"), ('.cc', '.cpp', '.cxx', '.h', '.hh', '.hpp', '.hxx')),
56
50
(_("OpenCL files"), ('.cl', )),
57
51
(_("Fortran files"), ('.f', '.for', '.f77', '.f90', '.f95', '.f2k')),
52
(_("IDL files"), ('.pro', )),
53
(_("MATLAB files"), ('.m', )),
58
54
(_("Patch and diff files"), ('.patch', '.diff', '.rej')),
59
55
(_("Batch files"), ('.bat', '.cmd')),
60
56
(_("Text files"), ('.txt',)),
61
57
(_("reStructured Text files"), ('.txt', '.rst')),
62
58
(_("gettext files"), ('.po', '.pot')),
59
(_("NSIS files"), ('.nsi', '.nsh')),
63
60
(_("Web page files"), ('.css', '.htm', '.html',)),
61
(_("XML files"), ('.xml',)),
62
(_("Enaml files"), ('.enaml',)),
64
63
(_("Configuration files"), ('.properties', '.session', '.ini', '.inf',
65
64
'.reg', '.cfg', '.desktop')),
67
def _create_filter(title, ftypes):
68
return "%s (*%s)" % (title, " *".join(ftypes))
70
ALL_FILTER = "%s (*)" % _("All files")
68
72
def _get_filters(filetypes):
70
74
for title, ftypes in filetypes:
71
filters.append("%s (*%s)" % (title, " *".join(ftypes)))
72
filters.append("%s (*)" % _("All files"))
75
filters.append(_create_filter(title, ftypes))
76
filters.append(ALL_FILTER)
73
77
return ";;".join(filters)
75
79
def _get_extensions(filetypes):
112
133
'window/position': (10, 10),
113
134
'window/is_maximized': False,
114
135
'window/is_fullscreen': False,
136
'window/prefs_dialog_size': (745, 411),
115
137
'lightwindow/size': (650, 400),
116
138
'lightwindow/position': (30, 30),
117
139
'lightwindow/is_maximized': False,
118
140
'lightwindow/is_fullscreen': False,
142
# The following setting is currently not used but necessary from
143
# a programmatical point of view (see spyder.py):
144
# (may become useful in the future if we add a button to change
145
# settings within the "light mode")
146
'lightwindow/prefs_dialog_size': (745, 411),
148
'memory_usage/enable': True,
149
'memory_usage/timeout': 2000,
150
'cpu_usage/enable': False,
151
'cpu_usage/timeout': 2000,
120
153
('quick_layouts',
199
232
'umd/verbose': True,
200
233
'umd/namelist': ['guidata', 'guiqwt'],
201
234
'light_background': True,
202
'ipython_set_color': True,
203
235
'merge_output_channels': os.name != 'nt',
204
236
'colorize_sys_stderr': os.name != 'nt',
240
'font/family': MONOSPACE,
242
'font/italic': False,
245
'use_gui_completion': True,
247
'show_calltips': False,
248
'ask_before_closing': True,
249
'object_inspector': True,
250
'buffer_size': 10000,
252
'pylab/autoload': True,
254
'pylab/inline/figure_format': 0,
255
'pylab/inline/resolution': 72,
256
'pylab/inline/width': 6,
257
'pylab/inline/height': 4,
258
'startup/run_lines': '',
259
'startup/use_run_file': False,
260
'startup/run_file': '',
261
'open_ipython_at_startup': False,
262
'greedy_completer': False,
264
'symbolic_math': False,
206
268
('variable_explorer',
208
270
'shortcut': "Ctrl+Shift+V",
364
429
CONF = UserConfig('spyder', defaults=DEFAULTS, load=(not DEV), version='2.4.0',
365
430
subfolder=SUBFOLDER, backup=True, raw_mode=True)
366
432
# Removing old .spyder.ini location:
367
433
old_location = osp.join(get_home_dir(), '.spyder.ini')
368
434
if osp.isfile(old_location):
369
435
os.remove(old_location)
373
def add_image_path(path):
374
if not osp.isdir(path):
377
IMG_PATH.append(path)
378
for _root, dirs, _files in os.walk(path):
380
IMG_PATH.append(osp.join(path, dir))
382
add_image_path(get_module_data_path('spyderlib', relpath='images'))
384
from spyderlib.otherplugins import PLUGIN_PATH
385
if PLUGIN_PATH is not None:
386
add_image_path(osp.join(PLUGIN_PATH, 'images'))
389
def get_image_path(name, default="not_found.png"):
390
"""Return image absolute path"""
391
for img_path in IMG_PATH:
392
full_path = osp.join(img_path, name)
393
if osp.isfile(full_path):
394
return osp.abspath(full_path)
395
if default is not None:
396
return osp.abspath(osp.join(img_path, default))
398
def get_icon( name, default=None ):
399
"""Return image inside a QIcon object"""
401
return QIcon(get_image_path(name))
402
elif isinstance(default, QIcon):
403
icon_path = get_image_path(name, default=None)
404
return default if icon_path is None else QIcon(icon_path)
406
return QIcon(get_image_path(name, default))
408
def get_image_label( name, default="not_found.png" ):
409
"""Return image inside a QLabel object"""
411
label.setPixmap(QPixmap(get_image_path(name, default)))
414
def font_is_installed(font):
415
"""Check if font is installed"""
416
return [fam for fam in QFontDatabase().families() if unicode(fam)==font]
418
def get_family(families):
419
"""Return the first installed font family in family list"""
420
if not isinstance(families, list):
421
families = [ families ]
422
for family in families:
423
if font_is_installed(family):
426
print "Warning: None of the following fonts is installed: %r" % families
427
return QFont().family()
430
def get_font(section, option=None):
431
"""Get console font properties depending on OS and user options"""
432
font = FONT_CACHE.get((section, option))
438
families = CONF.get(section, option+"/family", None)
441
family = get_family(families)
442
weight = QFont.Normal
443
italic = CONF.get(section, option+'/italic', False)
444
if CONF.get(section, option+'/bold', False):
446
size = CONF.get(section, option+'/size', 9)
447
font = QFont(family, size, weight)
448
font.setItalic(italic)
449
FONT_CACHE[(section, option)] = font
452
def set_font(font, section, option=None):
458
CONF.set(section, option+'/family', unicode(font.family()))
459
CONF.set(section, option+'/size', float(font.pointSize()))
460
CONF.set(section, option+'/italic', int(font.italic()))
461
CONF.set(section, option+'/bold', int(font.bold()))
462
FONT_CACHE[(section, option)] = font
465
def get_shortcut(context, name, default=NoDefault):
466
"""Get keyboard shortcut (key sequence string)"""
467
return CONF.get('shortcuts', '%s/%s' % (context, name), default=default)
469
def set_shortcut(context, name, keystr):
470
"""Set keyboard shortcut (key sequence string)"""
471
CONF.set('shortcuts', '%s/%s' % (context, name), keystr)
473
def iter_shortcuts():
474
"""Iterate over keyboard shortcuts"""
475
for option in CONF.options('shortcuts'):
476
context, name = option.split("/", 1)
477
yield context, name, get_shortcut(context, name)
479
def reset_shortcuts():
480
"""Reset keyboard shortcuts to default values"""
481
CONF.remove_section('shortcuts')
484
from spyderlib.widgets.sourcecode.syntaxhighlighters import (
485
COLOR_SCHEME_KEYS, COLOR_SCHEME_NAMES, COLORS)
486
def get_color_scheme(name):
487
"""Get syntax color scheme"""
489
for key in COLOR_SCHEME_KEYS:
490
color_scheme[key] = CONF.get("color_schemes", "%s/%s" % (name, key))
493
def set_color_scheme(name, color_scheme, replace=True):
494
"""Set syntax color scheme"""
495
section = "color_schemes"
496
names = CONF.get("color_schemes", "names", [])
497
for key in COLOR_SCHEME_KEYS:
498
option = "%s/%s" % (name, key)
499
value = CONF.get(section, option, default=None)
500
if value is None or replace or name not in names:
501
CONF.set(section, option, color_scheme[key])
502
names.append(unicode(name))
503
CONF.set(section, "names", sorted(list(set(names))))
505
def set_default_color_scheme(name, replace=True):
506
"""Reset color scheme to default values"""
507
assert name in COLOR_SCHEME_NAMES
508
set_color_scheme(name, COLORS[name], replace=replace)
510
for _name in COLOR_SCHEME_NAMES:
511
set_default_color_scheme(_name, replace=False)
512
CUSTOM_COLOR_SCHEME_NAME = "Custom"
513
set_color_scheme(CUSTOM_COLOR_SCHEME_NAME, COLORS["Spyder"], replace=False)