Add basic editor actions

This commit is contained in:
Kovid Goyal 2013-11-03 14:01:14 +05:30
parent 9a96eea0e8
commit f6554d74bb
5 changed files with 74 additions and 5 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -22,3 +22,5 @@ def current_container():
def set_current_container(container): def set_current_container(container):
global _current_container global _current_container
_current_container = container _current_container = container
actions = {}

View File

@ -21,7 +21,7 @@ from calibre.ebooks.oeb.polish.container import get_container as _gc, clone_cont
from calibre.ebooks.oeb.polish.replace import rename_files from calibre.ebooks.oeb.polish.replace import rename_files
from calibre.gui2 import error_dialog, choose_files, question_dialog, info_dialog from calibre.gui2 import error_dialog, choose_files, question_dialog, info_dialog
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.tweak_book import set_current_container, current_container, tprefs from calibre.gui2.tweak_book import set_current_container, current_container, tprefs, actions
from calibre.gui2.tweak_book.undo import GlobalUndoHistory from calibre.gui2.tweak_book.undo import GlobalUndoHistory
from calibre.gui2.tweak_book.save import SaveManager from calibre.gui2.tweak_book.save import SaveManager
from calibre.gui2.tweak_book.editor import editor_from_syntax, syntax_from_mime from calibre.gui2.tweak_book.editor import editor_from_syntax, syntax_from_mime
@ -49,6 +49,7 @@ class Boss(QObject):
fl.reorder_spine.connect(self.reorder_spine) fl.reorder_spine.connect(self.reorder_spine)
fl.rename_requested.connect(self.rename_requested) fl.rename_requested.connect(self.rename_requested)
fl.edit_file.connect(self.edit_file_requested) fl.edit_file.connect(self.edit_file_requested)
self.gui.central.current_editor_changed.connect(self.apply_current_editor_state)
def mkdtemp(self): def mkdtemp(self):
self.container_count += 1 self.container_count += 1
@ -217,11 +218,12 @@ class Boss(QObject):
editor = self.editors.get(name, None) editor = self.editors.get(name, None)
if editor is None: if editor is None:
editor = self.editors[name] = editor_from_syntax(syntax, self.gui.editor_tabs) editor = self.editors[name] = editor_from_syntax(syntax, self.gui.editor_tabs)
editor.undo_redo_state_changed.connect(self.editor_undo_redo_state_changed)
editor.modification_state_changed.connect(self.editor_modification_state_changed)
self.gui.central.add_editor(name, editor) self.gui.central.add_editor(name, editor)
c = current_container() c = current_container()
editor.load_text(c.decode(c.open(name).read())) editor.load_text(c.decode(c.open(name).read()))
self.gui.central.show_editor(editor) self.gui.central.show_editor(editor)
self.gui.keyboard.set_mode(syntax)
def edit_file_requested(self, name, syntax, mime): def edit_file_requested(self, name, syntax, mime):
if name in self.editors: if name in self.editors:
@ -234,6 +236,33 @@ class Boss(QObject):
_('Editing of files of type %s is not supported' % mime), show=True) _('Editing of files of type %s is not supported' % mime), show=True)
self.edit_file(name, syntax) self.edit_file(name, syntax)
def do_editor_undo(self):
ed = self.gui.central.current_editor
if ed is not None:
ed.undo()
def do_editor_redo(self):
ed = self.gui.central.current_editor
if ed is not None:
ed.redo()
def editor_undo_redo_state_changed(self, *args):
self.apply_current_editor_state(update_keymap=False)
def editor_modification_state_changed(self, *args):
self.apply_current_editor_state(update_keymap=False)
def apply_current_editor_state(self, update_keymap=True):
ed = self.gui.central.current_editor
if ed is not None:
actions['editor-undo'].setEnabled(ed.undo_available)
actions['editor-redo'].setEnabled(ed.redo_available)
actions['editor-save'].setEnabled(ed.is_modified)
self.gui.keyboard.set_mode(ed.syntax)
def do_editor_save(self):
pass # TODO: Implement this
# Shutdown {{{ # Shutdown {{{
def quit(self): def quit(self):
if not self.confirm_quit(): if not self.confirm_quit():

View File

@ -8,11 +8,13 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
from PyQt4.Qt import QMainWindow, Qt, QApplication, pyqtSignal from PyQt4.Qt import QMainWindow, Qt, QApplication, pyqtSignal
from calibre.gui2.tweak_book import actions
from calibre.gui2.tweak_book.editor.text import TextEdit from calibre.gui2.tweak_book.editor.text import TextEdit
class Editor(QMainWindow): class Editor(QMainWindow):
modification_state_changed = pyqtSignal(object) modification_state_changed = pyqtSignal(object)
undo_redo_state_changed = pyqtSignal(object, object)
def __init__(self, syntax, parent=None): def __init__(self, syntax, parent=None):
QMainWindow.__init__(self, parent) QMainWindow.__init__(self, parent)
@ -23,10 +25,28 @@ class Editor(QMainWindow):
self.setCentralWidget(self.editor) self.setCentralWidget(self.editor)
self.editor.modificationChanged.connect(self.modification_state_changed.emit) self.editor.modificationChanged.connect(self.modification_state_changed.emit)
self.create_toolbars() self.create_toolbars()
self.undo_available = False
self.redo_available = False
self.editor.undoAvailable.connect(self._undo_available)
self.editor.redoAvailable.connect(self._redo_available)
def _undo_available(self, available):
self.undo_available = available
self.undo_redo_state_changed.emit(self.undo_available, self.redo_available)
def _redo_available(self, available):
self.redo_available = available
self.undo_redo_state_changed.emit(self.undo_available, self.redo_available)
def load_text(self, raw): def load_text(self, raw):
self.editor.load_text(raw, syntax=self.syntax) self.editor.load_text(raw, syntax=self.syntax)
def undo(self):
self.editor.undo()
def redo(self):
self.editor.redo()
@dynamic_property @dynamic_property
def is_modified(self): def is_modified(self):
def fget(self): def fget(self):
@ -38,6 +58,9 @@ class Editor(QMainWindow):
def create_toolbars(self): def create_toolbars(self):
self.action_bar = b = self.addToolBar(_('Edit actions tool bar')) self.action_bar = b = self.addToolBar(_('Edit actions tool bar'))
b.setObjectName('action_bar') # Needed for saveState b.setObjectName('action_bar') # Needed for saveState
b.addAction(actions['editor-save'])
b.addAction(actions['editor-undo'])
b.addAction(actions['editor-redo'])
def launch_editor(path_to_edit, path_is_raw=False, syntax='html'): def launch_editor(path_to_edit, path_is_raw=False, syntax='html'):

View File

@ -8,11 +8,11 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
from PyQt4.Qt import ( from PyQt4.Qt import (
QDockWidget, Qt, QLabel, QIcon, QAction, QApplication, QWidget, QDockWidget, Qt, QLabel, QIcon, QAction, QApplication, QWidget,
QVBoxLayout, QStackedWidget, QTabWidget, QImage, QPixmap) QVBoxLayout, QStackedWidget, QTabWidget, QImage, QPixmap, pyqtSignal)
from calibre.constants import __appname__, get_version from calibre.constants import __appname__, get_version
from calibre.gui2.main_window import MainWindow from calibre.gui2.main_window import MainWindow
from calibre.gui2.tweak_book import current_container, tprefs from calibre.gui2.tweak_book import current_container, tprefs, actions
from calibre.gui2.tweak_book.file_list import FileListWidget from calibre.gui2.tweak_book.file_list import FileListWidget
from calibre.gui2.tweak_book.job import BlockingJob from calibre.gui2.tweak_book.job import BlockingJob
from calibre.gui2.tweak_book.boss import Boss from calibre.gui2.tweak_book.boss import Boss
@ -21,6 +21,8 @@ from calibre.gui2.tweak_book.keyboard import KeyboardManager
class Central(QStackedWidget): class Central(QStackedWidget):
' The central widget, hosts the editors ' ' The central widget, hosts the editors '
current_editor_changed = pyqtSignal()
def __init__(self, parent=None): def __init__(self, parent=None):
QStackedWidget.__init__(self, parent) QStackedWidget.__init__(self, parent)
self.welcome = w = QLabel('<p>'+_( self.welcome = w = QLabel('<p>'+_(
@ -47,6 +49,7 @@ class Central(QStackedWidget):
self.modified_icon = QIcon(QPixmap.fromImage(i)) self.modified_icon = QIcon(QPixmap.fromImage(i))
else: else:
self.modified_icon = QIcon(I('modified.png')) self.modified_icon = QIcon(I('modified.png'))
self.editor_tabs.currentChanged.connect(self.current_editor_changed)
def add_editor(self, name, editor): def add_editor(self, name, editor):
fname = name.rpartition('/')[2] fname = name.rpartition('/')[2]
@ -65,6 +68,10 @@ class Central(QStackedWidget):
modified = getattr(editor, 'is_modified', False) modified = getattr(editor, 'is_modified', False)
tb.setTabIcon(i, self.modified_icon if modified else QIcon()) tb.setTabIcon(i, self.modified_icon if modified else QIcon())
@property
def current_editor(self):
return self.editor_tabs.currentWidget()
class Main(MainWindow): class Main(MainWindow):
APP_NAME = _('Tweak Book') APP_NAME = _('Tweak Book')
@ -113,7 +120,7 @@ class Main(MainWindow):
group = _('Global Actions') group = _('Global Actions')
def reg(icon, text, target, sid, keys, description): def reg(icon, text, target, sid, keys, description):
ac = QAction(QIcon(I(icon)), text, self) ac = actions[sid] = QAction(QIcon(I(icon)), text, self)
ac.setObjectName('action-' + sid) ac.setObjectName('action-' + sid)
ac.triggered.connect(target) ac.triggered.connect(target)
if isinstance(keys, type('')): if isinstance(keys, type('')):
@ -132,6 +139,14 @@ class Main(MainWindow):
self.action_save.setEnabled(False) self.action_save.setEnabled(False)
self.action_quit = reg('quit.png', _('&Quit'), self.boss.quit, 'quit', 'Ctrl+Q', _('Quit')) self.action_quit = reg('quit.png', _('&Quit'), self.boss.quit, 'quit', 'Ctrl+Q', _('Quit'))
# Editor actions
self.action_editor_undo = reg('edit-undo.png', _('&Undo'), self.boss.do_editor_undo, 'editor-undo', 'Ctrl+Z',
_('Undo typing'))
self.action_editor_redo = reg('edit-redo.png', _('&Redo'), self.boss.do_editor_redo, 'editor-redo', 'Ctrl+Y',
_('Redo typing'))
self.action_editor_save = reg('save.png', _('&Save'), self.boss.do_editor_save, 'editor-save', 'Ctrl+S',
_('Save changes to the current file'))
def create_menubar(self): def create_menubar(self):
b = self.menuBar() b = self.menuBar()