11
11
# pylint: disable-msg=R0911
12
12
# pylint: disable-msg=R0201
14
from PyQt4.QtGui import (QVBoxLayout, QFileDialog, QMessageBox, QInputDialog,
15
QLineEdit, QPushButton, QGroupBox, QLabel, QTabWidget,
17
from PyQt4.QtCore import SIGNAL, QString, Qt
14
from spyderlib.qt.QtGui import (QVBoxLayout, QFileDialog, QMessageBox,
15
QInputDialog, QLineEdit, QPushButton,
16
QGroupBox, QLabel, QTabWidget, QFontComboBox)
17
from spyderlib.qt.QtCore import SIGNAL, QString, Qt
20
20
import os.path as osp
23
23
STDOUT = sys.stdout
26
from spyderlib.config import get_icon, CONF
26
from spyderlib.config import get_icon, CONF, _
27
27
from spyderlib.utils import (programs, remove_trailing_single_backslash,
29
29
from spyderlib.utils.qthelpers import create_action, mimedata2url
37
37
class ExternalConsoleConfigPage(PluginConfigPage):
38
38
def setup_page(self):
39
interface_group = QGroupBox(self.tr("Interface"))
39
interface_group = QGroupBox(_("Interface"))
40
40
font_group = self.create_fontgroup(option=None, text=None,
41
41
fontfilters=QFontComboBox.MonospacedFonts)
42
42
newcb = self.create_checkbox
43
singletab_box = newcb(self.tr("One tab per script"), 'single_tab')
44
showtime_box = newcb(self.tr("Show elapsed time"), 'show_elapsed_time')
45
icontext_box = newcb(self.tr("Show icons and text"), 'show_icontext')
43
singletab_box = newcb(_("One tab per script"), 'single_tab')
44
showtime_box = newcb(_("Show elapsed time"), 'show_elapsed_time')
45
icontext_box = newcb(_("Show icons and text"), 'show_icontext')
48
48
interface_layout = QVBoxLayout()
52
52
interface_group.setLayout(interface_layout)
54
54
# Source Code Group
55
display_group = QGroupBox(self.tr("Source code"))
55
display_group = QGroupBox(_("Source code"))
56
56
buffer_spin = self.create_spinbox(
57
self.tr("Buffer: "), self.tr(" lines"),
57
_("Buffer: "), _(" lines"),
58
58
'max_line_count', min_=0, max_=1000000, step=100,
59
tip=self.tr("Set maximum line count"))
60
wrap_mode_box = newcb(self.tr("Wrap lines"), 'wrap')
59
tip=_("Set maximum line count"))
60
wrap_mode_box = newcb(_("Wrap lines"), 'wrap')
62
62
display_layout = QVBoxLayout()
63
63
display_layout.addWidget(buffer_spin)
65
65
display_group.setLayout(display_layout)
67
67
# Background Color Group
68
bg_group = QGroupBox(self.tr("Background color"))
69
bg_label = QLabel(self.tr("This option will be applied the next time "
68
bg_group = QGroupBox(_("Background color"))
69
bg_label = QLabel(_("This option will be applied the next time "
70
70
"a Python console or a terminal is opened."))
71
71
bg_label.setWordWrap(True)
72
lightbg_box = newcb(self.tr("Light background (white color)"),
72
lightbg_box = newcb(_("Light background (white color)"),
73
73
'light_background')
74
ipybg_box = newcb(self.tr("Set the appropriate IPython color option"),
74
ipybg_box = newcb(_("Set the appropriate IPython color option"),
75
75
'ipython_set_color')
76
76
ipybg_box.setEnabled(programs.is_module_installed("IPython"))
77
77
bg_layout = QVBoxLayout()
81
81
bg_group.setLayout(bg_layout)
83
83
# Advanced settings
84
source_group = QGroupBox(self.tr("Source code"))
85
completion_box = newcb(self.tr("Automatic code completion"),
84
source_group = QGroupBox(_("Source code"))
85
completion_box = newcb(_("Automatic code completion"),
86
86
'codecompletion/auto')
87
case_comp_box = newcb(self.tr("Case sensitive code completion"),
87
case_comp_box = newcb(_("Case sensitive code completion"),
88
88
'codecompletion/case_sensitive')
89
show_single_box = newcb(self.tr("Show single completion"),
89
show_single_box = newcb(_("Show single completion"),
90
90
'codecompletion/show_single')
91
comp_enter_box = newcb(self.tr("Enter key selects completion"),
91
comp_enter_box = newcb(_("Enter key selects completion"),
92
92
'codecompletion/enter_key')
93
calltips_box = newcb(self.tr("Balloon tips"), 'calltips')
93
calltips_box = newcb(_("Balloon tips"), 'calltips')
94
94
inspector_box = newcb(
95
self.tr("Automatic notification to object inspector"),
95
_("Automatic notification to object inspector"),
96
96
'object_inspector', default=True,
97
tip=self.tr("If this option is enabled, object inspector\n"
97
tip=_("If this option is enabled, object inspector\n"
98
98
"will automatically show informations on functions\n"
99
99
"entered in console (this is triggered when entering\n"
100
100
"a left parenthesis after a valid function name)"))
109
109
source_group.setLayout(source_layout)
112
umd_group = QGroupBox(self.tr("User Module Deleter (UMD)"))
113
umd_label = QLabel(self.tr("UMD forces Python to reload modules "
112
umd_group = QGroupBox(_("User Module Deleter (UMD)"))
113
umd_label = QLabel(_("UMD forces Python to reload modules "
114
114
"imported when executing a script in the "
115
115
"external console with the 'runfile' function"))
116
116
umd_label.setWordWrap(True)
117
umd_enabled_box = newcb(self.tr("Enable UMD"), 'umd/enabled',
118
msg_if_enabled=True, msg_warning=self.tr(
117
umd_enabled_box = newcb(_("Enable UMD"), 'umd/enabled',
118
msg_if_enabled=True, msg_warning=_(
119
119
"This option will enable the User Module Deleter (UMD) "
120
120
"in Python/IPython interpreters. UMD forces Python to "
121
121
"reload deeply modules during import when running a "
131
131
"attribute <b>Qt.WA_DeleteOnClose</b> on your main "
132
132
"window, using the <b>setAttribute</b> method)"),
134
umd_verbose_box = newcb(self.tr("Show reloaded modules list"),
135
'umd/verbose', msg_info=self.tr(
134
umd_verbose_box = newcb(_("Show reloaded modules list"),
135
'umd/verbose', msg_info=_(
136
136
"Please note that these changes will "
137
137
"be applied only to new Python/IPython "
140
140
umd_namelist_btn = QPushButton(
141
self.tr("Set UMD excluded (not reloaded) modules"))
141
_("Set UMD excluded (not reloaded) modules"))
142
142
self.connect(umd_namelist_btn, SIGNAL('clicked()'),
143
143
self.plugin.set_umd_namelist)
150
150
umd_group.setLayout(umd_layout)
153
startup_group = QGroupBox(self.tr("Startup"))
154
pystartup_box = newcb(self.tr("Open a Python interpreter at startup"),
153
startup_group = QGroupBox(_("Startup"))
154
pystartup_box = newcb(_("Open a Python interpreter at startup"),
155
155
'open_python_at_startup')
156
ipystartup_box = newcb(self.tr("Open an IPython interpreter at startup"),
156
ipystartup_box = newcb(_("Open an IPython interpreter at startup"),
157
157
'open_ipython_at_startup')
158
158
ipystartup_box.setEnabled(programs.is_module_installed('IPython'))
163
163
startup_group.setLayout(startup_layout)
166
monitor_group = QGroupBox(self.tr("Monitor"))
167
monitor_label = QLabel(self.tr("The monitor provides introspection "
166
monitor_group = QGroupBox(_("Monitor"))
167
monitor_label = QLabel(_("The monitor provides introspection "
168
168
"features to console: code completion, "
169
169
"calltips and variable explorer. "
170
170
"Because it relies on several modules, "
171
171
"disabling the monitor may be useful "
172
172
"to accelerate console startup."))
173
173
monitor_label.setWordWrap(True)
174
monitor_box = newcb(self.tr("Enable monitor"), 'monitor/enabled')
174
monitor_box = newcb(_("Enable monitor"), 'monitor/enabled')
175
175
for obj in (completion_box, case_comp_box, show_single_box,
176
176
comp_enter_box, calltips_box):
177
177
self.connect(monitor_box, SIGNAL("toggled(bool)"), obj.setEnabled)
183
183
monitor_group.setLayout(monitor_layout)
186
pyqt_group = QGroupBox(self.tr("PyQt"))
187
pyqt_label = QLabel(self.tr("PyQt installs an input hook that "
186
pyqt_group = QGroupBox(_("PyQt"))
187
pyqt_label = QLabel(_("PyQt installs an input hook that "
188
188
"allows creating and interacting with widgets in an "
189
189
"interactive interpreter without blocking it. It is "
190
190
"strongly recommended to remove it on Windows "
191
191
"platforms (it has no effect in IPython)."))
192
192
pyqt_label.setWordWrap(True)
193
pyqt_hook_box = newcb(self.tr("Remove PyQt input hook"),
193
pyqt_hook_box = newcb(_("Remove PyQt input hook"),
194
194
'remove_pyqt_inputhook')
195
pyqt_setapi_box = newcb(_("Ignore API change errors "
197
'ignore_sip_setapi_errors')
199
from sip import setapi
201
pyqt_setapi_box.setDisabled(True)
196
203
pyqt_layout = QVBoxLayout()
197
204
pyqt_layout.addWidget(pyqt_label)
198
205
pyqt_layout.addWidget(pyqt_hook_box)
206
pyqt_layout.addWidget(pyqt_setapi_box)
199
207
pyqt_group.setLayout(pyqt_layout)
202
ipython_group = QGroupBox(self.tr("IPython"))
203
ipython_edit = self.create_lineedit(self.tr(
210
ipython_group = QGroupBox(_("IPython"))
211
ipython_edit = self.create_lineedit(_(
204
212
"IPython interpreter command line options:\n"
205
213
"(Qt4 and matplotlib support: -q4thread -pylab)"),
206
214
'ipython_options', alignment=Qt.Vertical)
211
219
ipython_group.setEnabled(programs.is_module_installed("IPython"))
213
221
# Matplotlib Group
214
mpl_group = QGroupBox(self.tr("Matplotlib"))
215
mpl_label = QLabel(self.tr("Patching Matplotlib library will add a "
216
"button to customize figure options "
217
"(curves/images plot parameters). This "
218
"Spyder feature has been integrated in "
222
mpl_group = QGroupBox(_("Matplotlib"))
223
mpl_label = QLabel(_("Patching Matplotlib library will add a "
224
"button to customize figure options "
225
"(curves/images plot parameters)."))
220
226
mpl_label.setWordWrap(True)
221
mpl_patch_box = newcb(self.tr("Patch Matplotlib figures"),
227
mpl_patch_box = newcb(_("Patch Matplotlib figures"),
222
228
'mpl_patch/enabled')
223
mpl_backend_edit = self.create_lineedit(self.tr("Matplotlib backend "
229
mpl_backend_edit = self.create_lineedit(_("Matplotlib backend "
224
230
"(default: Qt4Agg):"),
225
231
'mpl_patch/backend', "Qt4Agg",
226
self.tr("Set the GUI toolkit "
232
_("Set the GUI toolkit "
227
233
"used by Matplotlib to "
229
235
alignment=Qt.Vertical)
239
245
mpl_group.setEnabled(programs.is_module_installed('matplotlib'))
242
ets_group = QGroupBox(self.tr("Enthought Tool Suite"))
243
ets_label = QLabel(self.tr("Enthought Tool Suite (ETS) supports "
248
ets_group = QGroupBox(_("Enthought Tool Suite"))
249
ets_label = QLabel(_("Enthought Tool Suite (ETS) supports "
244
250
"PyQt4 (qt4) and wxPython (wx) graphical "
245
251
"user interfaces."))
246
252
ets_label.setWordWrap(True)
247
ets_edit = self.create_lineedit(self.tr("ETS_TOOLKIT "
253
ets_edit = self.create_lineedit(_("ETS_TOOLKIT "
248
254
"(default value: qt4):"),
249
255
'ets_backend', default='qt4',
250
256
alignment=Qt.Vertical)
259
265
tabs = QTabWidget()
260
266
tabs.addTab(self.create_tab(font_group, interface_group, display_group,
263
269
tabs.addTab(self.create_tab(monitor_group, source_group),
264
self.tr("Introspection"))
265
271
tabs.addTab(self.create_tab(startup_group, umd_group),
266
self.tr("Advanced settings"))
272
_("Advanced settings"))
267
273
tabs.addTab(self.create_tab(pyqt_group, ipython_group, mpl_group,
269
self.tr("External modules"))
275
_("External modules"))
271
277
vlayout = QVBoxLayout()
272
278
vlayout.addWidget(tabs)
293
299
self.python_count = 0
294
300
self.terminal_count = 0
303
from sip import setapi
305
self.set_option('ignore_sip_setapi_errors', False)
296
307
python_startup = self.get_option('open_python_at_startup', None)
297
308
ipython_startup = self.get_option('open_ipython_at_startup', None)
298
309
if ipython_startup is None:
459
470
old_shell = self.shellwidgets[index]
460
471
if old_shell.is_running():
461
472
answer = QMessageBox.question(self, self.get_plugin_title(),
462
self.tr("%1 is already running in a separate process.\n"
463
"Do you want to kill the process before starting "
464
"a new one?").arg(osp.basename(fname)),
473
_("%s is already running in a separate process.\n"
474
"Do you want to kill the process before starting "
475
"a new one?") % osp.basename(fname),
465
476
QMessageBox.Yes | QMessageBox.Cancel)
466
477
if answer == QMessageBox.Yes:
467
478
old_shell.process.kill()
483
494
ets_backend = self.get_option('ets_backend', 'qt4')
484
495
remove_pyqt_inputhook = self.get_option('remove_pyqt_inputhook',
497
ignore_sip_setapi_errors = self.get_option(
498
'ignore_sip_setapi_errors', True)
486
499
umd_enabled = self.get_option('umd/enabled')
487
500
umd_namelist = self.get_option('umd/namelist')
488
501
umd_verbose = self.get_option('umd/verbose')
503
516
mpl_patch_enabled=mpl_patch_enabled,
504
517
mpl_backend=mpl_backend,
505
518
remove_pyqt_inputhook=remove_pyqt_inputhook,
519
ignore_sip_setapi_errors=ignore_sip_setapi_errors,
506
520
autorefresh_timeout=ar_timeout,
507
521
autorefresh_state=ar_state,
508
522
light_background=light_background,
581
595
fname = id(shellwidget)
582
596
if os.name == 'nt':
583
tab_name = self.tr("Command Window")
597
tab_name = _("Command Window")
585
tab_name = self.tr("Terminal")
599
tab_name = _("Terminal")
586
600
self.terminal_count += 1
587
601
tab_name += (" %d" % self.terminal_count)
588
602
tab_icon1 = get_icon('cmdprompt.png')
636
650
#------ SpyderPluginWidget API ---------------------------------------------
637
651
def get_plugin_title(self):
638
652
"""Return widget title"""
639
return self.tr('Console')
641
655
def get_plugin_icon(self):
642
656
"""Return widget icon"""
652
666
def get_plugin_actions(self):
653
667
"""Return a list of actions related to plugin"""
654
668
interpreter_action = create_action(self,
655
self.tr("Open &interpreter"), None,
656
'python.png', self.tr("Open a Python interpreter"),
669
_("Open &interpreter"), None,
670
'python.png', _("Open a Python interpreter"),
657
671
triggered=self.open_interpreter)
658
672
if os.name == 'nt':
659
text = self.tr("Open &command prompt")
660
tip = self.tr("Open a Windows command prompt")
673
text = _("Open &command prompt")
674
tip = _("Open a Windows command prompt")
662
text = self.tr("Open &terminal")
663
tip = self.tr("Open a terminal window inside Spyder")
676
text = _("Open &terminal")
677
tip = _("Open a terminal window inside Spyder")
664
678
terminal_action = create_action(self, text, None, 'cmdprompt.png', tip,
665
679
triggered=self.open_terminal)
666
680
run_action = create_action(self,
667
self.tr("&Run..."), None,
668
'run_small.png', self.tr("Run a Python script"),
682
'run_small.png', _("Run a Python script"),
669
683
triggered=self.run_script)
671
685
run_menu_actions = [interpreter_action]
673
687
self.menu_actions = [interpreter_action, terminal_action, run_action]
675
689
ipython_action = create_action(self,
676
self.tr("Open IPython interpreter"), None,
690
_("Open IPython interpreter"), None,
678
self.tr("Open an IPython interpreter"),
692
_("Open an IPython interpreter"),
679
693
triggered=self.open_ipython)
680
694
if programs.is_module_installed("IPython"):
681
695
self.menu_actions.insert(1, ipython_action)
844
858
"""Run a Python script"""
845
859
self.emit(SIGNAL('redirect_stdio(bool)'), False)
846
860
filename = QFileDialog.getOpenFileName(self,
847
self.tr("Run Python script"), os.getcwdu(),
848
self.tr("Python scripts")+" (*.py ; *.pyw ; *.ipy)")
861
_("Run Python script"), os.getcwdu(),
862
_("Python scripts")+" (*.py ; *.pyw ; *.ipy)")
849
863
self.emit(SIGNAL('redirect_stdio(bool)'), True)
851
865
self.start(fname=unicode(filename), wdir=None, args='',
854
868
def set_umd_namelist(self):
855
869
"""Set UMD excluded modules name list"""
856
arguments, valid = QInputDialog.getText(self, self.tr('UMD'),
857
self.tr('UMD excluded modules:\n'
870
arguments, valid = QInputDialog.getText(self, _('UMD'),
871
_('UMD excluded modules:\n'
858
872
'(example: guidata, guiqwt)'),
859
873
QLineEdit.Normal,
860
874
", ".join(self.get_option('umd/namelist')))
866
880
if programs.is_module_installed(module_name)]
867
881
invalid = ", ".join(set(namelist)-set(fixed_namelist))
869
QMessageBox.warning(self, self.tr('UMD'),
870
self.tr("The following modules are not "
871
"installed on your machine:\n%1"
872
).arg(invalid), QMessageBox.Ok)
873
QMessageBox.information(self, self.tr('UMD'),
874
self.tr("Please note that these changes will "
875
"be applied only to new Python/IPython "
883
QMessageBox.warning(self, _('UMD'),
884
_("The following modules are not "
885
"installed on your machine:\n%s"
886
) % invalid, QMessageBox.Ok)
887
QMessageBox.information(self, _('UMD'),
888
_("Please note that these changes will "
889
"be applied only to new Python/IPython "
890
"interpreters"), QMessageBox.Ok)
879
892
fixed_namelist = []
880
893
self.set_option('umd/namelist', fixed_namelist)