diff --git a/spyderlib/plugins/help.py b/spyderlib/plugins/help.py index f110fbb6897..f405c475b14 100644 --- a/spyderlib/plugins/help.py +++ b/spyderlib/plugins/help.py @@ -21,12 +21,13 @@ import sys # Local imports -from spyderlib import dependencies from spyderlib.config.base import get_conf_path, get_module_source_path, _ from spyderlib.config.ipython import QTCONSOLE_INSTALLED from spyderlib.config.main import CONF from spyderlib.config.gui import get_color_scheme, get_font, set_font from spyderlib.utils import programs +from spyderlib.utils.help.sphinxify import (CSS_PATH, sphinxify, warning, + generate_context, usage) from spyderlib.utils.qthelpers import (create_toolbutton, add_actions, create_action) from spyderlib.widgets.comboboxes import EditableComboBox @@ -44,19 +45,6 @@ else: IPythonControlWidget = None # analysis:ignore -# Check if we can import Sphinx to activate rich text mode -try: - from spyderlib.utils.help.sphinxify import (CSS_PATH, sphinxify, warning, - generate_context, usage) - sphinx_version = programs.get_module_version('sphinx') -except (ImportError, TypeError): - sphinxify = sphinx_version = None # analysis:ignore - -# To add sphinx dependency to the Dependencies dialog -SPHINX_REQVER = '>=0.6.6' -dependencies.add("sphinx", _("Rich text help"), - required_version=SPHINX_REQVER) - class ObjectComboBox(EditableComboBox): """ @@ -158,14 +146,12 @@ def setup_page(self): features_group = QGroupBox(_("Additional features")) math_box = self.create_checkbox(_("Render mathematical equations"), 'math') - req_sphinx = sphinx_version is not None and \ - programs.is_module_installed('sphinx', '>=1.1') + req_sphinx = programs.is_module_installed('sphinx', '>=1.1') math_box.setEnabled(req_sphinx) if not req_sphinx: + sphinx_ver = programs.get_module_version('sphinx') sphinx_tip = _("This feature requires Sphinx 1.1 or superior.") - if sphinx_version is not None: - sphinx_tip += "\n" + _("Sphinx %s is currently installed." - ) % sphinx_version + sphinx_tip += "\n" + _("Sphinx %s is currently installed.") % sphinx_ver math_box.setToolTip(sphinx_tip) features_layout = QVBoxLayout() @@ -434,8 +420,7 @@ def __init__(self, parent): # Plain text docstring option self.docstring = True - self.rich_help = sphinxify is not None \ - and self.get_option('rich_mode', True) + self.rich_help = self.get_option('rich_mode', True) self.plain_text_action = create_action(self, _("Plain Text"), toggled=self.toggle_plain_text) @@ -482,7 +467,6 @@ def __init__(self, parent): self.switch_to_plain_text() self.plain_text_action.setChecked(not self.rich_help) self.rich_text_action.setChecked(self.rich_help) - self.rich_text_action.setEnabled(sphinxify is not None) self.source_changed() # Main layout @@ -494,15 +478,11 @@ def __init__(self, parent): self.setLayout(layout) # Add worker thread for handling rich text rendering - if sphinxify is None: - self._sphinx_thread = None - else: - self._sphinx_thread = SphinxThread( + self._sphinx_thread = SphinxThread( html_text_no_doc=warning(self.no_doc_string)) - self._sphinx_thread.html_ready.connect( + self._sphinx_thread.html_ready.connect( self._on_sphinx_thread_html_ready) - self._sphinx_thread.error_msg.connect( - self._on_sphinx_thread_error_msg) + self._sphinx_thread.error_msg.connect(self._on_sphinx_thread_error_msg) # Render internal links view = self.rich_text.webview @@ -551,8 +531,7 @@ def refresh_plugin(self): """Refresh widget""" if self._starting_up: self._starting_up = False - if sphinxify is not None: - self.switch_to_rich_text() + self.switch_to_rich_text() self.show_intro_message() def apply_plugin_settings(self, options): @@ -788,10 +767,7 @@ def show_tutorial(self): img_path = osp.join(tutorial_path, 'static', 'images') tutorial = osp.join(tutorial_path, 'tutorial.rst') text = open(tutorial).read() - if sphinxify is not None: - self.show_rich_text(text, collapse=True, img_path=img_path) - else: - self.show_plain_text(text) + self.show_rich_text(text, collapse=True, img_path=img_path) def handle_link_clicks(self, url): url = to_text_string(url.toString()) @@ -979,13 +955,14 @@ def _on_sphinx_thread_error_msg(self, error_msg): """ Display error message on Sphinx rich text failure""" self._sphinx_thread.wait() self.plain_text_action.setChecked(True) + sphinx_ver = programs.get_module_version('sphinx') QMessageBox.critical(self, _('Help'), _("The following error occured when calling " "Sphinx %s.
Incompatible Sphinx " "version or doc string decoding failed." "

Error message:
%s" - ) % (sphinx_version, error_msg)) + ) % (sphinx_ver, error_msg)) def show_help(self, obj_text, ignore_unknown=False): """Show help""" diff --git a/spyderlib/spyder.py b/spyderlib/spyder.py index c48dc8a756b..354a9671880 100644 --- a/spyderlib/spyder.py +++ b/spyderlib/spyder.py @@ -818,7 +818,11 @@ def create_edit_action(text, tr_text, icon): self.toolbarslist.append(self.workingdirectory) # Help plugin - if CONF.get('help', 'enable'): + dependencies.add("sphinx", _("Show help for objects in the Editor and " + "Consoles in a dedicated pane"), + required_version='>=0.6.6') + if CONF.get('help', 'enable') and \ + programs.is_module_installed('sphinx'): self.set_splash(_("Loading help...")) from spyderlib.plugins.help import Help self.help = Help(self) @@ -959,8 +963,11 @@ def create_edit_action(text, tr_text, icon): icon=ima.icon('DialogHelpButton'), triggered=lambda : programs.start_file(spyder_doc)) - tut_action = create_action(self, _("Spyder tutorial"), - triggered=self.help.show_tutorial) + if self.help is not None: + tut_action = create_action(self, _("Spyder tutorial"), + triggered=self.help.show_tutorial) + else: + tut_action = None #----- Tours self.tour = tour.AnimatedTour(self) @@ -987,10 +994,9 @@ def trigger(i=i, self=self): # closure needed! self.tours_menu = None self.help_menu_actions = [doc_action, tut_action, self.tours_menu, - None, - report_action, dep_action, - self.check_updates_action, support_action, - None] + None, report_action, dep_action, + self.check_updates_action, support_action, + None] # Python documentation if get_python_doc_path() is not None: pydoc_act = create_action(self, _("Python documentation"), @@ -998,7 +1004,7 @@ def trigger(i=i, self=self): # closure needed! programs.start_file(get_python_doc_path())) self.help_menu_actions.append(pydoc_act) # IPython documentation - if self.ipyconsole is not None: + if self.ipyconsole is not None and self.help is not None: ipython_menu = QMenu(_("IPython documentation"), self) intro_action = create_action(self, _("Intro to IPython"), triggered=self.ipyconsole.show_intro) @@ -1258,7 +1264,9 @@ def post_visible_setup(self): self.console.dockwidget.hide() # Show Help and Consoles by default - plugins_to_show = [self.help] + plugins_to_show = [] + if self.help is not None: + plugins_to_show.append(self.help) if self.ipyconsole is not None: if self.ipyconsole.isvisible: plugins_to_show += [self.extconsole, self.ipyconsole]