diff --git a/src/calibre/utils/pyconsole/__init__.py b/src/calibre/utils/pyconsole/__init__.py index 0dfa9398e1..06a7011132 100644 --- a/src/calibre/utils/pyconsole/__init__.py +++ b/src/calibre/utils/pyconsole/__init__.py @@ -8,14 +8,18 @@ __docformat__ = 'restructuredtext en' import sys from calibre import prints as prints_ -from calibre.utils.config import Config, StringConfig +from calibre.utils.config import Config, ConfigProxy -def console_config(defaults=None): - desc=_('Settings to control the calibre content server') - c = Config('console', desc) if defaults is None else StringConfig(defaults, desc) +def console_config(): + desc='Settings to control the calibre console' + c = Config('console', desc) - c.add_opt('--theme', default='default', help='The color theme') + c.add_opt('theme', default='default', help='The color theme') + + return c + +prefs = ConfigProxy(console_config()) def prints(*args, **kwargs): diff --git a/src/calibre/utils/pyconsole/console.py b/src/calibre/utils/pyconsole/console.py index f741562f03..b0ecce0cb3 100644 --- a/src/calibre/utils/pyconsole/console.py +++ b/src/calibre/utils/pyconsole/console.py @@ -6,16 +6,18 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' import sys, textwrap, traceback, StringIO +from functools import partial from PyQt4.Qt import QTextEdit, Qt, QTextFrameFormat, pyqtSignal, \ - QCoreApplication + QCoreApplication, QColor, QPalette, QMenu, QActionGroup from pygments.lexers import PythonLexer, PythonTracebackLexer +from pygments.styles import get_all_styles from calibre.constants import __appname__, __version__ from calibre.utils.pyconsole.formatter import Formatter from calibre.utils.pyconsole.repl import Interpreter, DummyFile -from calibre.utils.pyconsole import prints +from calibre.utils.pyconsole import prints, prefs from calibre.gui2 import error_dialog class EditBlock(object): # {{{ @@ -47,6 +49,28 @@ class Prepender(object): # {{{ self.console.cursor_pos = self.opos # }}} +class ThemeMenu(QMenu): + + def __init__(self, parent): + QMenu.__init__(self, _('Choose theme (needs restart)')) + parent.addMenu(self) + self.group = QActionGroup(self) + current = prefs['theme'] + alls = list(sorted(get_all_styles())) + if current not in alls: + current = prefs['theme'] = 'default' + self.actions = [] + for style in alls: + ac = self.group.addAction(style) + if current == style: + ac.setChecked(True) + self.actions.append(ac) + ac.triggered.connect(partial(self.set_theme, style)) + self.addAction(ac) + + def set_theme(self, style, *args): + prefs['theme'] = style + class Console(QTextEdit): @@ -99,8 +123,16 @@ class Console(QTextEdit): self.doc.setMaximumBlockCount(10000) self.lexer = PythonLexer(ensurenl=False) self.tb_lexer = PythonTracebackLexer() - self.formatter = Formatter(prompt, continuation, style='default') - self.setStyleSheet(self.formatter.stylesheet) + + self.context_menu = cm = QMenu(self) # {{{ + cm.theme = ThemeMenu(cm) + # }}} + + self.formatter = Formatter(prompt, continuation, style=prefs['theme']) + p = QPalette() + p.setColor(p.Base, QColor(self.formatter.background_color)) + p.setColor(p.Text, QColor(self.formatter.color)) + self.setPalette(p) self.key_dispatcher = { # {{{ Qt.Key_Enter : self.enter_pressed, @@ -127,6 +159,10 @@ class Console(QTextEdit): sys.excepthook = self.unhandled_exception + def contextMenuEvent(self, event): + self.context_menu.popup(event.globalPos()) + event.accept() + # Prompt management {{{ diff --git a/src/calibre/utils/pyconsole/formatter.py b/src/calibre/utils/pyconsole/formatter.py index 6e7d982a82..17360fecb3 100644 --- a/src/calibre/utils/pyconsole/formatter.py +++ b/src/calibre/utils/pyconsole/formatter.py @@ -48,10 +48,6 @@ class Formatter(object): self.styles[ttype] = fmt - self.stylesheet = ''' - QTextEdit { color: %s; background-color: %s } - '''%(self.color, self.background_color) - def get_fmt(self, token): if type(token) != type(Token.Generic): token = string_to_tokentype(token)