From 68df332cadc7f4ba5c884306e485591063b75085 Mon Sep 17 00:00:00 2001 From: GRiker Date: Sat, 18 Sep 2010 05:14:41 -0600 Subject: [PATCH 01/14] GwR apple driver patch --- src/calibre/devices/apple/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index 5fe36faf75..0946bd2f51 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -739,7 +739,7 @@ class ITUNES(DriverBase): # Purge the booklist, self.cached_books, thumb cache for i,bl_book in enumerate(booklists[0]): - if DEBUG: + if False: self.log.info(" evaluating '%s' by '%s' uuid:%s" % (bl_book.title, bl_book.author,bl_book.uuid)) From 4416264c0289b80a7eda510c375591f88e1ab8d4 Mon Sep 17 00:00:00 2001 From: GRiker Date: Sat, 18 Sep 2010 19:43:02 -0600 Subject: [PATCH 02/14] GwR wip tweak_epub --- src/calibre/customize/builtins.py | 6 ++++- src/calibre/gui2/actions/tweak_epub.py | 34 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 src/calibre/gui2/actions/tweak_epub.py diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 68df832048..ec9f7e2bc2 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -666,13 +666,17 @@ class ActionCopyToLibrary(InterfaceActionBase): name = 'Copy To Library' actual_plugin = 'calibre.gui2.actions.copy_to_library:CopyToLibraryAction' +class ActionTweakEpub(InterfaceActionBase): + name = 'Tweak ePub' + actual_plugin = 'calibre.gui2.actions.tweak_epub:TweakEpubAction' + plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog, ActionConvert, ActionDelete, ActionEditMetadata, ActionView, ActionFetchNews, ActionSaveToDisk, ActionShowBookDetails, ActionRestart, ActionOpenFolder, ActionConnectShare, ActionSendToDevice, ActionHelp, ActionPreferences, ActionSimilarBooks, ActionAddToLibrary, ActionEditCollections, ActionChooseLibrary, - ActionCopyToLibrary] + ActionCopyToLibrary, ActionTweakEpub] # }}} diff --git a/src/calibre/gui2/actions/tweak_epub.py b/src/calibre/gui2/actions/tweak_epub.py new file mode 100755 index 0000000000..5f49c57379 --- /dev/null +++ b/src/calibre/gui2/actions/tweak_epub.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from calibre.gui2.actions import InterfaceAction + +class TweakEpubAction(InterfaceAction): + + name = 'Tweak ePub' + action_spec = (_('Edit ePub in situ'), 'document_open.png', None, None) + dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) + action_type = 'current' + + def genesis(self): + self.qaction.triggered.connect(self.edit_epub_in_situ) + print "gui2.actions.tweak_epub:TweakEpubAction.genesis()" + + def initialization_complete(self): + print "gui2.actions.tweak_epub:TweakEpubAction.initialization_complete()" + + def library_changed(self, db): + print "gui2.actions.tweak_epub:TweakEpubAction.library_changed()" + + def location_selected(self, loc): + print "gui2.actions.tweak_epub:TweakEpubAction.location_selected()" + + def shutting_down(self): + print "gui2.actions.tweak_epub:TweakEpubAction.shutting_down()" + + def edit_epub_in_situ(self, *args): + print "gui2.actions.tweak_epub:TweakEpubAction.edit_epub_in_situ()" From 90ff41dfb2ba554f64cb61dd5d1a6de599941b32 Mon Sep 17 00:00:00 2001 From: GRiker Date: Sun, 19 Sep 2010 03:54:39 -0600 Subject: [PATCH 03/14] KG fix for TweakEpub --- src/calibre/gui2/actions/tweak_epub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/actions/tweak_epub.py b/src/calibre/gui2/actions/tweak_epub.py index 5f49c57379..020e9c0382 100755 --- a/src/calibre/gui2/actions/tweak_epub.py +++ b/src/calibre/gui2/actions/tweak_epub.py @@ -11,7 +11,7 @@ class TweakEpubAction(InterfaceAction): name = 'Tweak ePub' action_spec = (_('Edit ePub in situ'), 'document_open.png', None, None) - dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) + #dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) action_type = 'current' def genesis(self): From cec2f873cb29b8868695da152467c8f9d3eb9ea5 Mon Sep 17 00:00:00 2001 From: GRiker Date: Mon, 20 Sep 2010 07:44:33 -0700 Subject: [PATCH 04/14] GwR wip tweak_epub --- src/calibre/gui2/dialogs/tweak_epub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/dialogs/tweak_epub.py b/src/calibre/gui2/dialogs/tweak_epub.py index cc5b526291..a78d26a9dc 100755 --- a/src/calibre/gui2/dialogs/tweak_epub.py +++ b/src/calibre/gui2/dialogs/tweak_epub.py @@ -117,7 +117,7 @@ class TweakEpub(QDialog, Ui_Dialog): # Write mimetype zf.write(os.path.join(self._exploded,'mimetype'), 'mimetype', compress_type=ZIP_STORED) # Write everything else - exclude_files = ['.DS_Store','mimetype','iTunesMetadata.plist'] + exclude_files = ['.DS_Store','mimetype','iTunesMetadata.plist','rebuilt.epub'] for root, dirs, files in os.walk(self._exploded): for fn in files: if fn in exclude_files: From 62d9449e88f6aa5a6a2e1234137f31ed3d9e25d9 Mon Sep 17 00:00:00 2001 From: GRiker Date: Mon, 20 Sep 2010 07:57:05 -0700 Subject: [PATCH 05/14] GwR wip tweak_epub --- src/calibre/gui2/dialogs/tweak_epub.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/dialogs/tweak_epub.py b/src/calibre/gui2/dialogs/tweak_epub.py index a78d26a9dc..c0ad79385b 100755 --- a/src/calibre/gui2/dialogs/tweak_epub.py +++ b/src/calibre/gui2/dialogs/tweak_epub.py @@ -71,8 +71,8 @@ class TweakEpub(QDialog, Ui_Dialog): prints(" killing file browser proc") #self._file_browser_proc.terminate() #self._file_browser_proc.kill() - #self._file_browser_send_signal() - #self._file_browser_proc = None + #self._file_browser_send_signal(?) + self._file_browser_proc = None # Delete directory containing exploded ePub if self._exploded is not None: @@ -93,6 +93,7 @@ class TweakEpub(QDialog, Ui_Dialog): elif iswindows: cmd = 'start explorer.exe /e,/root,%s' % self._exploded else: + # *** Kovid - need proper linux invocation here *** cmd = '' # *** Kovid - need a way of launching this process than can be killed in cleanup() *** From 57a8705ec1b869d97d04ceab75db9caf1426faad Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 13:27:55 -0600 Subject: [PATCH 06/14] Don't maintain a separate prompt buffer --- src/calibre/utils/pyconsole/editor.py | 49 +++++++++++++++------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/calibre/utils/pyconsole/editor.py b/src/calibre/utils/pyconsole/editor.py index 68b83539f2..431a10eda5 100644 --- a/src/calibre/utils/pyconsole/editor.py +++ b/src/calibre/utils/pyconsole/editor.py @@ -58,7 +58,6 @@ class Editor(QTextEdit): QTextEdit.__init__(self, parent) self.buf = '' self.prompt_frame = None - self.current_prompt = [''] self.allow_output = False self.prompt_frame_format = QTextFrameFormat() self.prompt_frame_format.setBorder(1) @@ -84,11 +83,21 @@ class Editor(QTextEdit): self.interpreter = Interpreter(parent=self) self.interpreter.show_error.connect(self.show_error) - #it = self.prompt_frame.begin() - #while not it.atEnd(): - # bl = it.currentBlock() - # prints(repr(bl.text())) - # it += 1 + print list(self.prompt()) + + + def prompt(self, strip_prompt_strings=True): + if not self.prompt_frame: + yield u'' if strip_prompt_strings else self.formatter.prompt + else: + it = self.prompt_frame.begin() + while not it.atEnd(): + bl = it.currentBlock() + t = unicode(bl.text()) + if strip_prompt_strings: + t = t[self.prompt_len:] + yield t + it += 1 # Rendering {{{ @@ -113,15 +122,16 @@ class Editor(QTextEdit): c.setPosition(self.prompt_frame.firstPosition()) def render_current_prompt(self): + cp = list(self.prompt()) self.clear_current_prompt() - for i, line in enumerate(self.current_prompt): + for i, line in enumerate(cp): start = i == 0 - end = i == len(self.current_prompt) - 1 + end = i == len(cp) - 1 self.formatter.render_prompt(not start, self.cursor) self.formatter.render(self.lexer.get_tokens(line), self.cursor) if not end: - self.cursor.insertText('\n') + self.cursor.insertBlock() def show_error(self, is_syntax_err, tb): if self.prompt_frame is not None: @@ -194,32 +204,29 @@ class Editor(QTextEdit): def enter_pressed(self): if self.prompt_frame is None: return - if self.current_prompt[0]: + cp = list(self.prompt()) + if cp[0]: c = self.root_frame.lastCursorPosition() self.setTextCursor(c) old_pf = self.prompt_frame self.prompt_frame = None oldbuf = self.buf self.buf = '' - ret = self.interpreter.runsource('\n'.join(self.current_prompt)) + ret = self.interpreter.runsource('\n'.join(cp)) if ret: # Incomplete command self.buf = oldbuf self.prompt_frame = old_pf - self.current_prompt.append('') + c = old_pf.lastCursorPosition() + c.insertBlock() + self.setTextCursor(c) else: # Command completed - self.current_prompt = [''] old_pf.setFrameFormat(QTextFrameFormat()) self.render_current_prompt() def text_typed(self, text): - if not self.current_prompt[0]: - self.cursor.beginEditBlock() - else: - self.cursor.joinPreviousEditBlock() - self.current_prompt[-1] += text - self.render_current_prompt() - self.cursor.endEditBlock() - + if self.prompt_frame is not None: + self.cursor.insertText(text) + self.render_current_prompt() # }}} From 111c73ab80549913cc405d86d09ca69ef648e583 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 13:46:11 -0600 Subject: [PATCH 07/14] ... --- .../utils/pyconsole/{editor.py => console.py} | 31 ++++++++++++------- src/calibre/utils/pyconsole/main.py | 4 +-- 2 files changed, 21 insertions(+), 14 deletions(-) rename src/calibre/utils/pyconsole/{editor.py => console.py} (96%) diff --git a/src/calibre/utils/pyconsole/editor.py b/src/calibre/utils/pyconsole/console.py similarity index 96% rename from src/calibre/utils/pyconsole/editor.py rename to src/calibre/utils/pyconsole/console.py index 431a10eda5..d95e86c7ef 100644 --- a/src/calibre/utils/pyconsole/editor.py +++ b/src/calibre/utils/pyconsole/console.py @@ -29,7 +29,7 @@ class EditBlock(object): # {{{ self.cursor.endEditBlock() # }}} -class Editor(QTextEdit): +class Console(QTextEdit): @property def doc(self): @@ -86,6 +86,8 @@ class Editor(QTextEdit): print list(self.prompt()) + # Prompt management {{{ + def prompt(self, strip_prompt_strings=True): if not self.prompt_frame: yield u'' if strip_prompt_strings else self.formatter.prompt @@ -99,15 +101,8 @@ class Editor(QTextEdit): yield t it += 1 - - # Rendering {{{ - - def render_block(self, text, restore_prompt=True): - self.formatter.render(self.lexer.get_tokens(text), self.cursor) - self.cursor.insertBlock() - self.cursor.movePosition(self.cursor.End) - if restore_prompt: - self.render_current_prompt() + def set_prompt(self, lines): + self.render_current_prompt(lines) def clear_current_prompt(self): if self.prompt_frame is None: @@ -121,8 +116,8 @@ class Editor(QTextEdit): c.removeSelectedText() c.setPosition(self.prompt_frame.firstPosition()) - def render_current_prompt(self): - cp = list(self.prompt()) + def render_current_prompt(self, lines=None): + cp = list(self.prompt()) if lines is None else lines self.clear_current_prompt() for i, line in enumerate(cp): @@ -133,6 +128,18 @@ class Editor(QTextEdit): if not end: self.cursor.insertBlock() + # }}} + + + # Non-prompt Rendering {{{ + + def render_block(self, text, restore_prompt=True): + self.formatter.render(self.lexer.get_tokens(text), self.cursor) + self.cursor.insertBlock() + self.cursor.movePosition(self.cursor.End) + if restore_prompt: + self.render_current_prompt() + def show_error(self, is_syntax_err, tb): if self.prompt_frame is not None: # At a prompt, so redirect output diff --git a/src/calibre/utils/pyconsole/main.py b/src/calibre/utils/pyconsole/main.py index c2694aae5f..af99ec66bb 100644 --- a/src/calibre/utils/pyconsole/main.py +++ b/src/calibre/utils/pyconsole/main.py @@ -10,7 +10,7 @@ from PyQt4.Qt import QMainWindow, QToolBar, QStatusBar, QLabel, QFont, Qt, \ QApplication from calibre.constants import __appname__, __version__ -from calibre.utils.pyconsole.editor import Editor +from calibre.utils.pyconsole.console import Console class MainWindow(QMainWindow): @@ -37,7 +37,7 @@ class MainWindow(QMainWindow): self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextOnly) # }}} - self.editor = Editor(parent=self) + self.editor = Console(parent=self) self.setCentralWidget(self.editor) From f770aa43bbf4a175cb614e437694732361209637 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 14:24:42 -0600 Subject: [PATCH 08/14] Left and right arrow keys work --- src/calibre/utils/pyconsole/console.py | 64 ++++++++++++++++++-------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/src/calibre/utils/pyconsole/console.py b/src/calibre/utils/pyconsole/console.py index d95e86c7ef..73a19e7958 100644 --- a/src/calibre/utils/pyconsole/console.py +++ b/src/calibre/utils/pyconsole/console.py @@ -45,18 +45,30 @@ class Console(QTextEdit): @property def cursor_pos(self): - pass - #pos = self.cursor.position() - self.prompt_frame.firstPosition() - #i = 0 - #for line in self.current_prompt: - # i += self.prompt_len + ''' + Return cursor position in prompt frame as (row, col). + row starts at 0 for the first line + col is 0 if the cursor is at the start of the line, 1 if it is after + the first character, n if it is after the nth char. + ''' + if self.prompt_frame is not None: + pos = self.cursor.position() + it = self.prompt_frame.begin() + lineno = 0 + while not it.atEnd(): + bl = it.currentBlock() + if bl.contains(pos): + return (lineno, pos - bl.position()) + it += 1 + lineno += 1 + return (-1, -1) def __init__(self, prompt='>>> ', continuation='... ', parent=None): QTextEdit.__init__(self, parent) - self.buf = '' + self.buf = [] self.prompt_frame = None self.allow_output = False self.prompt_frame_format = QTextFrameFormat() @@ -130,7 +142,6 @@ class Console(QTextEdit): # }}} - # Non-prompt Rendering {{{ def render_block(self, text, restore_prompt=True): @@ -143,26 +154,25 @@ class Console(QTextEdit): def show_error(self, is_syntax_err, tb): if self.prompt_frame is not None: # At a prompt, so redirect output - return prints(tb) + return prints(tb, end='') try: - self.buf += tb + self.buf.append(tb) if is_syntax_err: self.formatter.render_syntax_error(tb, self.cursor) else: self.formatter.render(self.tb_lexer.get_tokens(tb), self.cursor) except: - prints(tb) + prints(tb, end='') def show_output(self, raw): if self.prompt_frame is not None: # At a prompt, so redirect output - return prints(raw) + return prints(raw, end='') try: - self.current_prompt_range = None - self.buf += raw + self.buf.append(raw) self.formatter.render_raw(raw, self.cursor) except: - prints(raw) + prints(raw, end='') # }}} @@ -187,13 +197,29 @@ class Console(QTextEdit): QTextEdit.keyPressEvent(self, ev) def left_pressed(self): - pass + lineno, pos = self.cursor_pos + if lineno < 0: return + if pos > self.prompt_len: + c = self.cursor + c.movePosition(c.PreviousCharacter) + self.setTextCursor(c) + elif lineno > 0: + c = self.cursor + c.movePosition(c.Up) + c.movePosition(c.EndOfLine) + self.setTextCursor(c) def right_pressed(self): - if self.prompt_frame is not None: - c = self.cursor + lineno, pos = self.cursor_pos + if lineno < 0: return + c = self.cursor + lineno, pos = self.cursor_pos + cp = list(self.prompt(False)) + if pos < len(cp[lineno]): c.movePosition(c.NextCharacter) - self.setTextCursor(c) + elif lineno < len(cp)-1: + c.movePosition(c.NextCharacter, n=1+self.prompt_len) + self.setTextCursor(c) def home_pressed(self): if self.prompt_frame is not None: @@ -218,7 +244,7 @@ class Console(QTextEdit): old_pf = self.prompt_frame self.prompt_frame = None oldbuf = self.buf - self.buf = '' + self.buf = [] ret = self.interpreter.runsource('\n'.join(cp)) if ret: # Incomplete command self.buf = oldbuf From 4b981a5257be82a9f4cfaeb8fca32f48f54dc7d0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 14:58:24 -0600 Subject: [PATCH 09/14] Inserting, not just appending text now works --- src/calibre/utils/pyconsole/console.py | 68 +++++++++++++++++--------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/src/calibre/utils/pyconsole/console.py b/src/calibre/utils/pyconsole/console.py index 73a19e7958..19a24dfdd7 100644 --- a/src/calibre/utils/pyconsole/console.py +++ b/src/calibre/utils/pyconsole/console.py @@ -43,25 +43,6 @@ class Console(QTextEdit): def root_frame(self): return self.doc.rootFrame() - @property - def cursor_pos(self): - ''' - Return cursor position in prompt frame as (row, col). - row starts at 0 for the first line - col is 0 if the cursor is at the start of the line, 1 if it is after - the first character, n if it is after the nth char. - ''' - if self.prompt_frame is not None: - pos = self.cursor.position() - it = self.prompt_frame.begin() - lineno = 0 - while not it.atEnd(): - bl = it.currentBlock() - if bl.contains(pos): - return (lineno, pos - bl.position()) - it += 1 - lineno += 1 - return (-1, -1) def __init__(self, prompt='>>> ', @@ -95,11 +76,48 @@ class Console(QTextEdit): self.interpreter = Interpreter(parent=self) self.interpreter.show_error.connect(self.show_error) - print list(self.prompt()) - # Prompt management {{{ + @dynamic_property + def cursor_pos(self): + doc = ''' + The cursor position in the prompt has the form (row, col). + row starts at 0 for the first line + col is 0 if the cursor is at the start of the line, 1 if it is after + the first character, n if it is after the nth char. + ''' + + def fget(self): + if self.prompt_frame is not None: + pos = self.cursor.position() + it = self.prompt_frame.begin() + lineno = 0 + while not it.atEnd(): + bl = it.currentBlock() + if bl.contains(pos): + return (lineno, pos - bl.position()) + it += 1 + lineno += 1 + return (-1, -1) + + def fset(self, val): + row, col = val + if self.prompt_frame is not None: + it = self.prompt_frame.begin() + lineno = 0 + while not it.atEnd(): + if lineno == row: + c = self.cursor + c.setPosition(it.currentBlock().position()) + c.movePosition(c.NextCharacter, n=col) + self.setTextCursor(c) + break + it += 1 + lineno += 1 + + return property(fget=fget, fset=fset, doc=doc) + def prompt(self, strip_prompt_strings=True): if not self.prompt_frame: yield u'' if strip_prompt_strings else self.formatter.prompt @@ -128,7 +146,8 @@ class Console(QTextEdit): c.removeSelectedText() c.setPosition(self.prompt_frame.firstPosition()) - def render_current_prompt(self, lines=None): + def render_current_prompt(self, lines=None, restore_cursor=False): + row, col = self.cursor_pos cp = list(self.prompt()) if lines is None else lines self.clear_current_prompt() @@ -140,6 +159,9 @@ class Console(QTextEdit): if not end: self.cursor.insertBlock() + if row > -1 and restore_cursor: + self.cursor_pos = (row, col) + # }}} # Non-prompt Rendering {{{ @@ -259,7 +281,7 @@ class Console(QTextEdit): def text_typed(self, text): if self.prompt_frame is not None: self.cursor.insertText(text) - self.render_current_prompt() + self.render_current_prompt(restore_cursor=True) # }}} From fe6d962bee771a34dd4937b6f332e0d0d4114676 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 19:33:17 -0600 Subject: [PATCH 10/14] Use dialog instead of main window. Set console stylesheet based on pygments style. Don't block if there is a lot of output --- imgsrc/console.svg | 4339 ++++++++++++++++++++++ resources/images/console.png | Bin 0 -> 5110 bytes src/calibre/utils/pyconsole/__init__.py | 9 + src/calibre/utils/pyconsole/console.py | 117 +- src/calibre/utils/pyconsole/formatter.py | 14 +- src/calibre/utils/pyconsole/main.py | 44 +- 6 files changed, 4482 insertions(+), 41 deletions(-) create mode 100644 imgsrc/console.svg create mode 100644 resources/images/console.png diff --git a/imgsrc/console.svg b/imgsrc/console.svg new file mode 100644 index 0000000000..0d502bb1da --- /dev/null +++ b/imgsrc/console.svg @@ -0,0 +1,4339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/console.png b/resources/images/console.png new file mode 100644 index 0000000000000000000000000000000000000000..168f0ccb2a177087d2ee6157bb67166688c84c05 GIT binary patch literal 5110 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 -1 and restore_cursor: self.cursor_pos = (row, col) + self.ensureCursorVisible() + # }}} # Non-prompt Rendering {{{ @@ -185,16 +237,26 @@ class Console(QTextEdit): self.formatter.render(self.tb_lexer.get_tokens(tb), self.cursor) except: prints(tb, end='') + self.ensureCursorVisible() + QCoreApplication.processEvents() def show_output(self, raw): + def do_show(): + try: + self.buf.append(raw) + self.formatter.render_raw(raw, self.cursor) + except: + import traceback + prints(traceback.format_exc()) + prints(raw, end='') + if self.prompt_frame is not None: - # At a prompt, so redirect output - return prints(raw, end='') - try: - self.buf.append(raw) - self.formatter.render_raw(raw, self.cursor) - except: - prints(raw, end='') + with Prepender(self): + do_show() + else: + do_show() + self.ensureCursorVisible() + QCoreApplication.processEvents() # }}} @@ -203,16 +265,11 @@ class Console(QTextEdit): def keyPressEvent(self, ev): text = unicode(ev.text()) key = ev.key() - if key in (Qt.Key_Enter, Qt.Key_Return): - self.enter_pressed() - elif key == Qt.Key_Home: - self.home_pressed() - elif key == Qt.Key_End: - self.end_pressed() - elif key == Qt.Key_Left: - self.left_pressed() - elif key == Qt.Key_Right: - self.right_pressed() + action = self.key_dispatcher.get(key, None) + if callable(action): + action() + elif key in (Qt.Key_Escape,): + QTextEdit.keyPressEvent(self, ev) elif text: self.text_typed(text) else: @@ -230,6 +287,7 @@ class Console(QTextEdit): c.movePosition(c.Up) c.movePosition(c.EndOfLine) self.setTextCursor(c) + self.ensureCursorVisible() def right_pressed(self): lineno, pos = self.cursor_pos @@ -242,6 +300,7 @@ class Console(QTextEdit): elif lineno < len(cp)-1: c.movePosition(c.NextCharacter, n=1+self.prompt_len) self.setTextCursor(c) + self.ensureCursorVisible() def home_pressed(self): if self.prompt_frame is not None: @@ -249,12 +308,14 @@ class Console(QTextEdit): c.movePosition(c.StartOfLine) c.movePosition(c.NextCharacter, n=self.prompt_len) self.setTextCursor(c) + self.ensureCursorVisible() def end_pressed(self): if self.prompt_frame is not None: c = self.cursor c.movePosition(c.EndOfLine) self.setTextCursor(c) + self.ensureCursorVisible() def enter_pressed(self): if self.prompt_frame is None: @@ -267,7 +328,13 @@ class Console(QTextEdit): self.prompt_frame = None oldbuf = self.buf self.buf = [] - ret = self.interpreter.runsource('\n'.join(cp)) + self.running.emit() + try: + ret = self.interpreter.runsource('\n'.join(cp)) + except SystemExit: + ret = False + self.show_output('Raising SystemExit not allowed\n') + self.running_done.emit() if ret: # Incomplete command self.buf = oldbuf self.prompt_frame = old_pf @@ -275,7 +342,13 @@ class Console(QTextEdit): c.insertBlock() self.setTextCursor(c) else: # Command completed - old_pf.setFrameFormat(QTextFrameFormat()) + try: + old_pf.setFrameFormat(QTextFrameFormat()) + except RuntimeError: + # Happens if enough lines of output that the old + # frame was deleted + pass + self.render_current_prompt() def text_typed(self, text): diff --git a/src/calibre/utils/pyconsole/formatter.py b/src/calibre/utils/pyconsole/formatter.py index 7f99983ef6..9409007ec6 100644 --- a/src/calibre/utils/pyconsole/formatter.py +++ b/src/calibre/utils/pyconsole/formatter.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' from PyQt4.Qt import QTextCharFormat, QFont, QBrush, QColor from pygments.formatter import Formatter as PF -from pygments.token import Token +from pygments.token import Token, Generic class Formatter(object): @@ -22,11 +22,16 @@ class Formatter(object): pf = PF(**options) self.styles = {} self.normal = self.base_fmt() + self.background_color = pf.style.background_color + self.color = 'black' + for ttype, ndef in pf.style: fmt = self.base_fmt() if ndef['color']: fmt.setForeground(QBrush(QColor('#%s'%ndef['color']))) fmt.setUnderlineColor(QColor('#%s'%ndef['color'])) + if ttype == Generic.Output: + self.color = '#%s'%ndef['color'] if ndef['bold']: fmt.setFontWeight(QFont.Bold) if ndef['italic']: @@ -40,6 +45,11 @@ class Formatter(object): self.styles[ttype] = fmt + self.stylesheet = ''' + QTextEdit { color: %s; background-color: %s } + '''%(self.color, self.background_color) + + def base_fmt(self): fmt = QTextCharFormat() fmt.setFontFamily('monospace') @@ -74,7 +84,7 @@ class Formatter(object): def render_prompt(self, is_continuation, cursor): pr = self.continuation if is_continuation else self.prompt - fmt = self.styles[Token.Generic.Subheading] + fmt = self.styles[Generic.Prompt] cursor.insertText(pr, fmt) diff --git a/src/calibre/utils/pyconsole/main.py b/src/calibre/utils/pyconsole/main.py index af99ec66bb..f098ce2ee2 100644 --- a/src/calibre/utils/pyconsole/main.py +++ b/src/calibre/utils/pyconsole/main.py @@ -6,19 +6,31 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' __version__ = '0.1.0' -from PyQt4.Qt import QMainWindow, QToolBar, QStatusBar, QLabel, QFont, Qt, \ - QApplication +from functools import partial + +from PyQt4.Qt import QDialog, QToolBar, QStatusBar, QLabel, QFont, Qt, \ + QApplication, QIcon, QVBoxLayout from calibre.constants import __appname__, __version__ from calibre.utils.pyconsole.console import Console -class MainWindow(QMainWindow): +class MainWindow(QDialog): - def __init__(self, default_status_msg): + def __init__(self, + default_status_msg=_('Welcome to') + ' ' + __appname__+' console', + parent=None): - QMainWindow.__init__(self) + QDialog.__init__(self, parent) + self.l = QVBoxLayout() + self.setLayout(self.l) - self.resize(600, 700) + self.resize(800, 600) + + # Setup tool bar {{{ + self.tool_bar = QToolBar(self) + self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextOnly) + self.l.addWidget(self.tool_bar) + # }}} # Setup status bar {{{ self.status_bar = QStatusBar(self) @@ -28,25 +40,23 @@ class MainWindow(QMainWindow): self.status_bar._font.setBold(True) self.status_bar.defmsg.setFont(self.status_bar._font) self.status_bar.addWidget(self.status_bar.defmsg) - self.setStatusBar(self.status_bar) # }}} - # Setup tool bar {{{ - self.tool_bar = QToolBar(self) - self.addToolBar(Qt.BottomToolBarArea, self.tool_bar) - self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextOnly) - # }}} - - self.editor = Console(parent=self) - self.setCentralWidget(self.editor) - + self.console = Console(parent=self) + self.console.running.connect(partial(self.status_bar.showMessage, + _('Code is running'))) + self.console.running_done.connect(self.status_bar.clearMessage) + self.l.addWidget(self.console) + self.l.addWidget(self.status_bar) + self.setWindowTitle(__appname__ + ' console') + self.setWindowIcon(QIcon(I('console.png'))) def main(): QApplication.setApplicationName(__appname__+' console') QApplication.setOrganizationName('Kovid Goyal') app = QApplication([]) - m = MainWindow(_('Welcome to') + ' ' + __appname__+' console') + m = MainWindow() m.show() app.exec_() From ec8164470b8b4ac54b2f16bba57f22a6e856be8b Mon Sep 17 00:00:00 2001 From: GRiker Date: Mon, 20 Sep 2010 19:39:33 -0700 Subject: [PATCH 11/14] GwR revisions tweak_epub --- src/calibre/gui2/dialogs/tweak_epub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/dialogs/tweak_epub.py b/src/calibre/gui2/dialogs/tweak_epub.py index c0ad79385b..379352f390 100755 --- a/src/calibre/gui2/dialogs/tweak_epub.py +++ b/src/calibre/gui2/dialogs/tweak_epub.py @@ -25,7 +25,6 @@ class TweakEpub(QDialog, Ui_Dialog): To do: - need way to kill file browser proc in cleanup() - - Windows file browser launch - linux file browser launch ''' @@ -109,6 +108,7 @@ class TweakEpub(QDialog, Ui_Dialog): zipextract(self._epub, self._exploded) self.display_exploded() self.rebuild_button.setEnabled(True) + self.explode_button.setEnabled(False) def rebuild(self): if DEBUG: From 3dfaa2cdaaeda5f56d5d39b02df61b1371942a58 Mon Sep 17 00:00:00 2001 From: GRiker Date: Mon, 20 Sep 2010 20:10:17 -0700 Subject: [PATCH 12/14] change to use open_local_file --- src/calibre/gui2/dialogs/tweak_epub.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/dialogs/tweak_epub.py b/src/calibre/gui2/dialogs/tweak_epub.py index 379352f390..a967ca310a 100755 --- a/src/calibre/gui2/dialogs/tweak_epub.py +++ b/src/calibre/gui2/dialogs/tweak_epub.py @@ -15,6 +15,7 @@ from PyQt4.Qt import QDialog, SIGNAL from calibre import prints from calibre.constants import iswindows, isosx, DEBUG +from calibre.gui2 import open_local_file from calibre.gui2.dialogs.tweak_epub_ui import Ui_Dialog from calibre.libunzip import extract as zipextract from calibre.ptempfile import PersistentTemporaryDirectory @@ -33,7 +34,7 @@ class TweakEpub(QDialog, Ui_Dialog): self._epub = epub self._exploded = None - self._file_browser_proc = None + #self._file_browser_proc = None self._output = None # Run the dialog setup generated from tweak_epub.ui @@ -64,14 +65,6 @@ class TweakEpub(QDialog, Ui_Dialog): ''' if DEBUG: prints("gui2.dialogs.tweak_epub:TweakEpub.cleanup()") - # Kill file browser proc - if self._file_browser_proc: - if DEBUG: - prints(" killing file browser proc") - #self._file_browser_proc.terminate() - #self._file_browser_proc.kill() - #self._file_browser_send_signal(?) - self._file_browser_proc = None # Delete directory containing exploded ePub if self._exploded is not None: @@ -87,6 +80,7 @@ class TweakEpub(QDialog, Ui_Dialog): ''' if DEBUG: prints("gui2.dialogs.tweak_epub:TweakEpub.display_exploded()") + ''' if isosx: cmd = 'open %s' % self._exploded elif iswindows: @@ -97,6 +91,8 @@ class TweakEpub(QDialog, Ui_Dialog): # *** Kovid - need a way of launching this process than can be killed in cleanup() *** self._file_browser_proc = subprocess.Popen(cmd, shell=True) + ''' + open_local_file(self._exploded) def explode(self): if DEBUG: From 3fff4da652dd242fbdeb52c8d5676043c02df7c4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 21:32:29 -0600 Subject: [PATCH 13/14] Infrastructure changes to launch pyconsole interpreter process --- src/calibre/utils/ipc/launch.py | 21 ++++++++++++--------- src/calibre/utils/ipc/worker.py | 4 ++++ src/calibre/utils/pyconsole/console.py | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/calibre/utils/ipc/launch.py b/src/calibre/utils/ipc/launch.py index 0de81ed644..aa93469119 100644 --- a/src/calibre/utils/ipc/launch.py +++ b/src/calibre/utils/ipc/launch.py @@ -22,13 +22,15 @@ class Worker(object): have the environment variable :envvar:`CALIBRE_WORKER` set. Useful attributes: ``is_alive``, ``returncode`` - usefule methods: ``kill`` + Useful methods: ``kill`` To launch child simply call the Worker object. By default, the child's output is redirected to an on disk file, the path to which is returned by the call. ''' + exe_name = 'calibre-parallel' + @property def osx_interpreter(self): exe = os.path.basename(sys.executable) @@ -41,32 +43,33 @@ class Worker(object): @property def executable(self): + e = self.exe_name if iswindows: return os.path.join(os.path.dirname(sys.executable), - 'calibre-parallel.exe' if isfrozen else \ - 'Scripts\\calibre-parallel.exe') + e+'.exe' if isfrozen else \ + 'Scripts\\%s.exe'%e) if isnewosx: - return os.path.join(sys.console_binaries_path, 'calibre-parallel') + return os.path.join(sys.console_binaries_path, e) if isosx: - if not isfrozen: return 'calibre-parallel' + if not isfrozen: return e contents = os.path.join(self.osx_contents_dir, 'console.app', 'Contents') return os.path.join(contents, 'MacOS', self.osx_interpreter) if isfrozen: - return os.path.join(getattr(sys, 'frozen_path'), 'calibre-parallel') + return os.path.join(getattr(sys, 'frozen_path'), e) - c = os.path.join(sys.executables_location, 'calibre-parallel') + c = os.path.join(sys.executables_location, e) if os.access(c, os.X_OK): return c - return 'calibre-parallel' + return e @property def gui_executable(self): if isnewosx: - return os.path.join(sys.binaries_path, 'calibre-parallel') + return os.path.join(sys.binaries_path, self.exe_name) if isfrozen and isosx: return os.path.join(self.osx_contents_dir, diff --git a/src/calibre/utils/ipc/worker.py b/src/calibre/utils/ipc/worker.py index 73233840fe..b7510426aa 100644 --- a/src/calibre/utils/ipc/worker.py +++ b/src/calibre/utils/ipc/worker.py @@ -80,8 +80,12 @@ def main(): if isosx and 'CALIBRE_WORKER_ADDRESS' not in os.environ: # On some OS X computers launchd apparently tries to # launch the last run process from the bundle + # so launch the gui as usual from calibre.gui2.main import main as gui_main return gui_main(['calibre']) + if 'CALIBRE_LAUNCH_INTERPRETER' in os.environ: + from calibre.utils.pyconsole.interpreter import main + return main() address = cPickle.loads(unhexlify(os.environ['CALIBRE_WORKER_ADDRESS'])) key = unhexlify(os.environ['CALIBRE_WORKER_KEY']) resultf = unhexlify(os.environ['CALIBRE_WORKER_RESULT']) diff --git a/src/calibre/utils/pyconsole/console.py b/src/calibre/utils/pyconsole/console.py index 251e8424a0..f741562f03 100644 --- a/src/calibre/utils/pyconsole/console.py +++ b/src/calibre/utils/pyconsole/console.py @@ -47,6 +47,7 @@ class Prepender(object): # {{{ self.console.cursor_pos = self.opos # }}} + class Console(QTextEdit): running = pyqtSignal() From 88f980ad186859708aceb3907ae59d4052648ff3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Sep 2010 21:33:43 -0600 Subject: [PATCH 14/14] News download: Don't add inline table of contents when downloading news for the Kindle --- src/calibre/gui2/tools.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 7a516bb4ff..2f0452a773 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -217,6 +217,10 @@ def fetch_scheduled_recipe(arg): if 'output_profile' in ps: recs.append(('output_profile', ps['output_profile'], OptionRecommendation.HIGH)) + if ps['output_profile'] == 'kindle': + recs.append(('no_inline_toc', True, + OptionRecommendation.HIGH)) + lf = load_defaults('look_and_feel') if lf.get('base_font_size', 0.0) != 0.0: recs.append(('base_font_size', lf['base_font_size'],