mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fixes for viewer etc.
Fix: Remember maximized state when toggle fullscreen. New: Adding saved state: fullscreen state. New: Adding context menu item: search online, back (Backspace)/forward, toc, font size, fullscreen, exit (Esc). Fix: Hiding non-selection context menu items when showing selection context menu items. Fix: Hiding selection context menu items when showing image context menu items. Fix: Return in book list would not open viewer for selected items. Fix: The top book list row was not selected on program start, as intended. Fix: Reset quick search would unselect the book list selection even when not in a search. Fix: Reset quick search when in a search would not return selection to a book list row. Fix: Don't open empty viewer if no book is selected. Change: Removing fullscreen message because it's not useful for many users. New: Applying auto convert option for manual add too. New: Making the post import phase accessible to plugins (for metadata creation or conversion). New: Adding viewer option to not show the cover.
This commit is contained in:
parent
4fa4a7d9e0
commit
2772908a3c
@ -308,6 +308,10 @@ class FileTypePlugin(Plugin): # {{{
|
||||
#: to the database
|
||||
on_import = False
|
||||
|
||||
#: If True, this plugin is run after books are added
|
||||
#: to the database
|
||||
on_postimport = False
|
||||
|
||||
#: If True, this plugin is run just before a conversion
|
||||
on_preprocess = False
|
||||
|
||||
@ -337,6 +341,13 @@ class FileTypePlugin(Plugin): # {{{
|
||||
# Default implementation does nothing
|
||||
return path_to_ebook
|
||||
|
||||
def postimport(self, id):
|
||||
'''
|
||||
Run post import.
|
||||
|
||||
:param id: Library id of the added book.
|
||||
'''
|
||||
|
||||
# }}}
|
||||
|
||||
class MetadataReaderPlugin(Plugin): # {{{
|
||||
|
@ -104,14 +104,17 @@ def is_disabled(plugin):
|
||||
# File type plugins {{{
|
||||
|
||||
_on_import = {}
|
||||
_on_postimport = {}
|
||||
_on_preprocess = {}
|
||||
_on_postprocess = {}
|
||||
|
||||
def reread_filetype_plugins():
|
||||
global _on_import
|
||||
global _on_postimport
|
||||
global _on_preprocess
|
||||
global _on_postprocess
|
||||
_on_import = {}
|
||||
_on_postimport = {}
|
||||
_on_preprocess = {}
|
||||
_on_postprocess = {}
|
||||
|
||||
@ -122,6 +125,10 @@ def reread_filetype_plugins():
|
||||
if not _on_import.has_key(ft):
|
||||
_on_import[ft] = []
|
||||
_on_import[ft].append(plugin)
|
||||
if plugin.on_postimport:
|
||||
if not _on_postimport.has_key(ft):
|
||||
_on_postimport[ft] = []
|
||||
_on_postimport[ft].append(plugin)
|
||||
if plugin.on_preprocess:
|
||||
if not _on_preprocess.has_key(ft):
|
||||
_on_preprocess[ft] = []
|
||||
@ -163,6 +170,21 @@ run_plugins_on_preprocess = functools.partial(_run_filetype_plugins,
|
||||
occasion='preprocess')
|
||||
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
||||
occasion='postprocess')
|
||||
|
||||
def postimport_plugins(id, format):
|
||||
customization = config['plugin_customization']
|
||||
format = format.lower()
|
||||
for plugin in _on_postimport.get(format, []):
|
||||
if is_disabled(plugin):
|
||||
continue
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
with plugin:
|
||||
try:
|
||||
plugin.postimport(id)
|
||||
except:
|
||||
print 'Running file type plugin %s failed with traceback:'%plugin.name
|
||||
traceback.print_exc()
|
||||
|
||||
# }}}
|
||||
|
||||
# Plugin customization {{{
|
||||
|
@ -49,8 +49,9 @@ class EbookIterator(BookmarksMixin):
|
||||
|
||||
CHARACTERS_PER_PAGE = 1000
|
||||
|
||||
def __init__(self, pathtoebook, log=None):
|
||||
def __init__(self, pathtoebook, exclude_cover=False, log=None):
|
||||
self.log = log or default_log
|
||||
self.exclude_cover = exclude_cover
|
||||
pathtoebook = pathtoebook.strip()
|
||||
self.pathtoebook = os.path.abspath(pathtoebook)
|
||||
self.config = DynamicConfig(name='iterator')
|
||||
@ -139,8 +140,10 @@ class EbookIterator(BookmarksMixin):
|
||||
self.log.warn('Missing spine item:', repr(spath))
|
||||
|
||||
cover = self.opf.cover
|
||||
if cover and self.ebook_ext in {'lit', 'mobi', 'prc', 'opf', 'fb2',
|
||||
if cover:
|
||||
if self.ebook_ext in {'lit', 'mobi', 'prc', 'opf', 'fb2',
|
||||
'azw', 'azw3'}:
|
||||
if not self.exclude_cover:
|
||||
cfile = os.path.join(self.base, 'calibre_iterator_cover.html')
|
||||
rcpath = os.path.relpath(cover, self.base).replace(os.sep, '/')
|
||||
chtml = (TITLEPAGE%prepare_string_for_xml(rcpath, True)).encode('utf-8')
|
||||
@ -149,6 +152,8 @@ class EbookIterator(BookmarksMixin):
|
||||
self.spine[0:0] = [Spiny(cfile,
|
||||
mime_type='application/xhtml+xml')]
|
||||
self.delete_on_exit.append(cfile)
|
||||
elif self.exclude_cover:
|
||||
self.spine.remove(self.spine[0])
|
||||
|
||||
if self.opf.path_to_html_toc is not None and \
|
||||
self.opf.path_to_html_toc not in self.spine:
|
||||
|
@ -267,7 +267,6 @@ class ViewAction(InterfaceAction):
|
||||
|
||||
def _view_books(self, rows):
|
||||
if not rows or len(rows) == 0:
|
||||
self._launch_viewer()
|
||||
return
|
||||
|
||||
if not self._view_check(len(rows)):
|
||||
|
@ -99,6 +99,7 @@ class DBAdder(QObject): # {{{
|
||||
def __init__(self, parent, db, ids, nmap):
|
||||
QObject.__init__(self, parent)
|
||||
|
||||
self.parent = parent
|
||||
self.db, self.ids, self.nmap = db, dict(**ids), dict(**nmap)
|
||||
self.critical = {}
|
||||
self.number_of_books_added = 0
|
||||
@ -232,6 +233,11 @@ class DBAdder(QObject): # {{{
|
||||
with open(path, 'rb') as f:
|
||||
self.db.add_format(id, fmt, f, index_is_id=True,
|
||||
notify=False, replace=replace)
|
||||
if gprefs['auto_add_auto_convert']:
|
||||
of = prefs['output_format']
|
||||
if not of == fmt.lower():
|
||||
gui = self.parent._parent
|
||||
gui.iactions['Convert Books'].auto_convert([id], None, of)
|
||||
|
||||
# }}}
|
||||
|
||||
|
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
import functools
|
||||
|
||||
from PyQt4.Qt import Qt, QStackedWidget, QMenu, \
|
||||
QSize, QSizePolicy, QStatusBar, QLabel, QFont
|
||||
QSize, QSizePolicy, QStatusBar, QTimer, QLabel, QFont
|
||||
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.constants import (isosx, __appname__, preferred_encoding,
|
||||
@ -274,7 +274,7 @@ class LayoutMixin(object): # {{{
|
||||
|
||||
m = self.library_view.model()
|
||||
if m.rowCount(None) > 0:
|
||||
self.library_view.set_current_row(0)
|
||||
QTimer.singleShot(1, self.library_view.set_current_row)
|
||||
m.current_changed(self.library_view.currentIndex(),
|
||||
self.library_view.currentIndex())
|
||||
self.library_view.setFocus(Qt.OtherFocusReason)
|
||||
|
@ -754,6 +754,13 @@ class BooksView(QTableView): # {{{
|
||||
|
||||
# }}}
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if event.key() == Qt.Key_Return:
|
||||
selected_rows = [r.row() for r in self.selectionModel().selectedRows()]
|
||||
self.display_parent.iactions['View']._view_books(selected_rows)
|
||||
else:
|
||||
return super(BooksView, self).keyPressEvent(event)
|
||||
|
||||
@property
|
||||
def column_map(self):
|
||||
return self._model.column_map
|
||||
@ -777,7 +784,7 @@ class BooksView(QTableView): # {{{
|
||||
self.scrollTo(self.model().index(row, i), self.PositionAtCenter)
|
||||
break
|
||||
|
||||
def set_current_row(self, row, select=True):
|
||||
def set_current_row(self, row=0, select=True):
|
||||
if row > -1 and row < self.model().rowCount(QModelIndex()):
|
||||
h = self.horizontalHeader()
|
||||
logical_indices = list(range(h.count()))
|
||||
|
@ -128,7 +128,7 @@ class SearchBox2(QComboBox): # {{{
|
||||
def clear(self, emit_search=True):
|
||||
self.normalize_state()
|
||||
self.setEditText('')
|
||||
if emit_search:
|
||||
if self.in_a_search() and emit_search:
|
||||
self.search.emit('')
|
||||
self._in_a_search = False
|
||||
self.cleared.emit()
|
||||
@ -159,7 +159,6 @@ class SearchBox2(QComboBox): # {{{
|
||||
self.normalize_state()
|
||||
if self._in_a_search:
|
||||
self.changed.emit()
|
||||
self._in_a_search = False
|
||||
if event.key() in (Qt.Key_Return, Qt.Key_Enter):
|
||||
self.do_search()
|
||||
self.focus_to_library.emit()
|
||||
@ -424,6 +423,7 @@ class SearchBoxMixin(object): # {{{
|
||||
self.tags_view.clear()
|
||||
self.saved_search.clear()
|
||||
self.set_number_of_books_shown()
|
||||
self.focus_to_library()
|
||||
|
||||
def search_box_changed(self):
|
||||
self.saved_search.clear()
|
||||
@ -440,6 +440,8 @@ class SearchBoxMixin(object): # {{{
|
||||
|
||||
def focus_to_library(self):
|
||||
self.current_view().setFocus(Qt.OtherFocusReason)
|
||||
if not self.current_view().get_selected_ids():
|
||||
self.current_view().set_current_row()
|
||||
|
||||
# }}}
|
||||
|
||||
|
@ -41,6 +41,8 @@ def config(defaults=None):
|
||||
help=_('Default language for hyphenation rules'))
|
||||
c.add_opt('remember_current_page', default=True,
|
||||
help=_('Save the current position in the document, when quitting'))
|
||||
c.add_opt('dont_show_cover', default=False,
|
||||
help=_('Don\'t show the cover.'))
|
||||
c.add_opt('wheel_flips_pages', default=False,
|
||||
help=_('Have the mouse wheel turn pages'))
|
||||
c.add_opt('line_scrolling_stops_on_pagebreaks', default=False,
|
||||
@ -177,6 +179,7 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
||||
def load_options(self, opts):
|
||||
self.opt_remember_window_size.setChecked(opts.remember_window_size)
|
||||
self.opt_remember_current_page.setChecked(opts.remember_current_page)
|
||||
self.opt_dont_show_cover.setChecked(opts.dont_show_cover)
|
||||
self.opt_wheel_flips_pages.setChecked(opts.wheel_flips_pages)
|
||||
self.opt_page_flip_duration.setValue(opts.page_flip_duration)
|
||||
fms = opts.font_magnification_step
|
||||
@ -267,6 +270,7 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
||||
c.set('max_fs_width', int(self.max_fs_width.value()))
|
||||
c.set('hyphenate', self.hyphenate.isChecked())
|
||||
c.set('remember_current_page', self.opt_remember_current_page.isChecked())
|
||||
c.set('dont_show_cover', self.opt_dont_show_cover.isChecked())
|
||||
c.set('wheel_flips_pages', self.opt_wheel_flips_pages.isChecked())
|
||||
c.set('page_flip_duration', self.opt_page_flip_duration.value())
|
||||
c.set('font_magnification_step',
|
||||
|
@ -605,6 +605,13 @@ QToolBox::tab:hover {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="opt_dont_show_cover">
|
||||
<property name="text">
|
||||
<string>Don't show the c&over (needs restart)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -16,6 +16,7 @@ from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
|
||||
|
||||
from calibre.gui2.viewer.flip import SlideFlip
|
||||
from calibre.gui2.shortcuts import Shortcuts
|
||||
from calibre.gui2 import open_url
|
||||
from calibre import prints
|
||||
from calibre.customize.ui import all_viewer_plugins
|
||||
from calibre.gui2.viewer.keys import SHORTCUTS
|
||||
@ -478,7 +479,12 @@ class DocumentView(QWebView): # {{{
|
||||
d = self.document
|
||||
self.unimplemented_actions = list(map(self.pageAction,
|
||||
[d.DownloadImageToDisk, d.OpenLinkInNewWindow, d.DownloadLinkToDisk,
|
||||
d.OpenImageInNewWindow, d.OpenLink, d.Reload]))
|
||||
d.OpenImageInNewWindow, d.OpenLink, d.Reload, d.InspectElement, d.Copy]))
|
||||
|
||||
self.search_online_action = QAction(QIcon(I('search.png')), _(''), self)
|
||||
self.search_online_action.setShortcut(Qt.CTRL+Qt.Key_E)
|
||||
self.search_online_action.triggered.connect(self.search_online)
|
||||
self.addAction(self.search_online_action)
|
||||
self.dictionary_action = QAction(QIcon(I('dictionary.png')),
|
||||
_('&Lookup in dictionary'), self)
|
||||
self.dictionary_action.setShortcut(Qt.CTRL+Qt.Key_L)
|
||||
@ -523,6 +529,44 @@ class DocumentView(QWebView): # {{{
|
||||
self.goto_location_action.setMenu(self.goto_location_menu)
|
||||
self.grabGesture(Qt.SwipeGesture)
|
||||
|
||||
self.toc_action = QAction(_('Table of contents'), self)
|
||||
self.toc_action.setCheckable(True)
|
||||
self.toc_action.triggered.connect(self.toggle_toc)
|
||||
|
||||
self.back_action = QAction(_('&Back'), self)
|
||||
self.back_action.triggered.connect(self.back)
|
||||
self.back_action.setShortcut(Qt.Key_Backspace)
|
||||
self.addAction(self.back_action)
|
||||
self.forward_action = QAction(_('&Forward'), self)
|
||||
self.forward_action.triggered.connect(self.forward)
|
||||
|
||||
self.magnify_fonts_action = QAction(_('Larger font'), self)
|
||||
self.magnify_fonts_action.triggered.connect(self.font_size_larger)
|
||||
self.restore_fonts_action = QAction(_('Normal font size'), self)
|
||||
self.restore_fonts_action.setCheckable(True)
|
||||
self.restore_fonts_action.triggered.connect(self.font_size_restore)
|
||||
self.shrink_fonts_action = QAction(_('Smaller font'), self)
|
||||
self.shrink_fonts_action.triggered.connect(self.font_size_smaller)
|
||||
|
||||
self.fullscreen_action = QAction(_('Full screen'), self)
|
||||
self.fullscreen_action.triggered.connect(self.toggle_fullscreen)
|
||||
self.fullscreen_action.setCheckable(True)
|
||||
self.fullscreen_action.setShortcut(Qt.Key_F11)
|
||||
self.addAction(self.fullscreen_action)
|
||||
|
||||
self.quit_action = QAction(_('Exit'), self)
|
||||
self.quit_action.triggered.connect(self.quit_toggle)
|
||||
self.quit_action.setShortcut(Qt.Key_Escape)
|
||||
self.addAction(self.quit_action)
|
||||
|
||||
def back(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.back()
|
||||
|
||||
def forward(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.forward()
|
||||
|
||||
def goto_next_section(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.goto_next_section()
|
||||
@ -539,6 +583,30 @@ class DocumentView(QWebView): # {{{
|
||||
if self.manager is not None:
|
||||
self.manager.goto_end()
|
||||
|
||||
def font_size_larger(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.font_size_larger()
|
||||
|
||||
def font_size_smaller(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.font_size_smaller()
|
||||
|
||||
def font_size_restore(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.font_size_restore()
|
||||
|
||||
def toggle_toc(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.toggle_toc()
|
||||
|
||||
def toggle_fullscreen(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.toggle_fullscreen()
|
||||
|
||||
def quit_toggle(self, *args):
|
||||
if self.manager is not None:
|
||||
self.manager.quit()
|
||||
|
||||
@property
|
||||
def copy_action(self):
|
||||
return self.pageAction(self.document.Copy)
|
||||
@ -579,6 +647,17 @@ class DocumentView(QWebView): # {{{
|
||||
if self.manager is not None:
|
||||
self.manager.selection_changed(unicode(self.document.selectedText()))
|
||||
|
||||
def _selectedText(self):
|
||||
t = self.selectedText().trimmed()
|
||||
if not t:
|
||||
return ""
|
||||
if t.size() > 40:
|
||||
t.truncate(40)
|
||||
t = t + "..."
|
||||
t = t.replace('&', '&&')
|
||||
t = "S&earch Google for '" + t + "'"
|
||||
return unicode(t)
|
||||
|
||||
def contextMenuEvent(self, ev):
|
||||
mf = self.document.mainFrame()
|
||||
r = mf.hitTestContent(ev.pos())
|
||||
@ -588,17 +667,52 @@ class DocumentView(QWebView): # {{{
|
||||
menu = self.document.createStandardContextMenu()
|
||||
for action in self.unimplemented_actions:
|
||||
menu.removeAction(action)
|
||||
text = unicode(self.selectedText())
|
||||
if text:
|
||||
menu.insertAction(list(menu.actions())[0], self.dictionary_action)
|
||||
menu.insertAction(list(menu.actions())[0], self.search_action)
|
||||
|
||||
if not img.isNull():
|
||||
menu.addAction(self.view_image_action)
|
||||
|
||||
text = self._selectedText()
|
||||
if text and img.isNull():
|
||||
copyAction = self.pageAction(self.document.Copy)
|
||||
copyAction.setText("&Copy")
|
||||
menu.addAction(copyAction)
|
||||
self.search_online_action.setText(text)
|
||||
menu.addAction(self.search_online_action)
|
||||
menu.addAction(self.dictionary_action)
|
||||
menu.addAction(self.search_action)
|
||||
|
||||
if not text and img.isNull():
|
||||
menu.addSeparator()
|
||||
menu.addAction(self.back_action)
|
||||
menu.addAction(self.forward_action)
|
||||
menu.addAction(self.goto_location_action)
|
||||
if self.document.in_fullscreen_mode and self.manager is not None:
|
||||
|
||||
menu.addSeparator()
|
||||
self.toc_action.setChecked(self.manager.toc.isVisible())
|
||||
menu.addAction(self.toc_action)
|
||||
|
||||
menu.addSeparator()
|
||||
menu.addAction(self.magnify_fonts_action)
|
||||
self.restore_fonts_action.setChecked(self.multiplier == 1)
|
||||
menu.addAction(self.restore_fonts_action)
|
||||
menu.addAction(self.shrink_fonts_action)
|
||||
|
||||
menu.addSeparator()
|
||||
inspectAction = self.pageAction(self.document.InspectElement)
|
||||
inspectAction.setText("I&nspect element")
|
||||
menu.addAction(inspectAction)
|
||||
|
||||
if not text and img.isNull():
|
||||
menu.addSeparator()
|
||||
if self.document.in_fullscreen_mode and self.manager is not None:
|
||||
self.manager.toggle_toolbar_action.setChecked(self.manager.tool_bar.isVisible())
|
||||
menu.addAction(self.manager.toggle_toolbar_action)
|
||||
self.fullscreen_action.setChecked(self.manager.isFullScreen())
|
||||
menu.addAction(self.fullscreen_action)
|
||||
|
||||
menu.addSeparator()
|
||||
menu.addAction(self.quit_action)
|
||||
|
||||
menu.exec_(ev.globalPos())
|
||||
|
||||
def lookup(self, *args):
|
||||
@ -613,6 +727,12 @@ class DocumentView(QWebView): # {{{
|
||||
if t:
|
||||
self.manager.search.set_search_string(t)
|
||||
|
||||
def search_online(self):
|
||||
t = unicode(self.selectedText()).strip()
|
||||
if t:
|
||||
url = 'https://www.google.com/search?q=' + QUrl().toPercentEncoding(t)
|
||||
open_url(QUrl.fromEncoded(url))
|
||||
|
||||
def set_manager(self, manager):
|
||||
self.manager = manager
|
||||
self.scrollbar = manager.horizontal_scrollbar
|
||||
@ -990,6 +1110,11 @@ class DocumentView(QWebView): # {{{
|
||||
self.multiplier -= amount
|
||||
return self.document.scroll_fraction
|
||||
|
||||
def restore_font_size(self):
|
||||
with self.document.page_position:
|
||||
self.multiplier = 1
|
||||
return self.document.scroll_fraction
|
||||
|
||||
def changeEvent(self, event):
|
||||
if event.type() == event.EnabledChange:
|
||||
self.update()
|
||||
|
@ -230,7 +230,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.action_reference_mode.setCheckable(True)
|
||||
self.action_reference_mode.triggered[bool].connect(self.view.reference_mode)
|
||||
self.action_metadata.triggered[bool].connect(self.metadata.setVisible)
|
||||
self.action_table_of_contents.toggled[bool].connect(self.set_toc_visible)
|
||||
self.action_table_of_contents.toggled[bool].connect(self.toggle_toc)
|
||||
self.action_copy.triggered[bool].connect(self.copy)
|
||||
self.action_font_size_larger.triggered.connect(self.font_size_larger)
|
||||
self.action_font_size_smaller.triggered.connect(self.font_size_smaller)
|
||||
@ -240,7 +240,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.action_find_next.triggered.connect(self.find_next)
|
||||
self.action_find_previous.triggered.connect(self.find_previous)
|
||||
self.action_full_screen.triggered[bool].connect(self.toggle_fullscreen)
|
||||
self.action_full_screen.setShortcuts([Qt.Key_F11, Qt.CTRL+Qt.SHIFT+Qt.Key_F])
|
||||
self.action_full_screen.setShortcut(Qt.CTRL+Qt.SHIFT+Qt.Key_F)
|
||||
self.action_full_screen.setToolTip(_('Toggle full screen (%s)') %
|
||||
_(' or ').join([unicode(x.toString(x.NativeText)) for x in
|
||||
self.action_full_screen.shortcuts()]))
|
||||
@ -274,35 +274,11 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.tool_bar2.setContextMenuPolicy(Qt.PreventContextMenu)
|
||||
self.tool_bar.widgetForAction(self.action_bookmark).setPopupMode(QToolButton.MenuButtonPopup)
|
||||
self.action_full_screen.setCheckable(True)
|
||||
self.full_screen_label = QLabel('''
|
||||
<center>
|
||||
<h1>%s</h1>
|
||||
<h3>%s</h3>
|
||||
<h3>%s</h3>
|
||||
<h3>%s</h3>
|
||||
</center>
|
||||
'''%(_('Full screen mode'),
|
||||
_('Right click to show controls'),
|
||||
_('Tap in the left or right page margin to turn pages'),
|
||||
_('Press Esc to quit')),
|
||||
self)
|
||||
self.full_screen_label.setVisible(False)
|
||||
self.full_screen_label.setStyleSheet('''
|
||||
QLabel {
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
color: black;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 20px;
|
||||
}
|
||||
''')
|
||||
self.window_mode_changed = None
|
||||
self.toggle_toolbar_action = QAction(_('Show/hide controls'), self)
|
||||
self.toggle_toolbar_action.setCheckable(True)
|
||||
self.toggle_toolbar_action.triggered.connect(self.toggle_toolbars)
|
||||
self.addAction(self.toggle_toolbar_action)
|
||||
self.full_screen_label_anim = QPropertyAnimation(
|
||||
self.full_screen_label, 'size')
|
||||
self.clock_label = QLabel('99:99', self)
|
||||
self.clock_label.setVisible(False)
|
||||
self.clock_label.setFocusPolicy(Qt.NoFocus)
|
||||
@ -324,11 +300,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.pos_label.setFocusPolicy(Qt.NoFocus)
|
||||
self.clock_timer = QTimer(self)
|
||||
self.clock_timer.timeout.connect(self.update_clock)
|
||||
self.esc_full_screen_action = a = QAction(self)
|
||||
self.addAction(a)
|
||||
a.setShortcut(Qt.Key_Escape)
|
||||
a.setEnabled(False)
|
||||
a.triggered.connect(self.action_full_screen.trigger)
|
||||
|
||||
self.print_menu = QMenu()
|
||||
self.print_menu.addAction(QIcon(I('print-preview.png')), _('Print Preview'))
|
||||
@ -374,8 +345,13 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.pending_restore = True
|
||||
self.load_path(self.view.last_loaded_path)
|
||||
|
||||
def set_toc_visible(self, yes):
|
||||
self.toc.setVisible(yes)
|
||||
def toggle_toc(self):
|
||||
if self.toc.isVisible():
|
||||
self.toc.setVisible(False)
|
||||
self.action_table_of_contents.setChecked(False)
|
||||
else:
|
||||
self.toc.setVisible(True)
|
||||
self.action_table_of_contents.setChecked(True)
|
||||
|
||||
def clear_recent_history(self, *args):
|
||||
vprefs.set('viewer_open_history', [])
|
||||
@ -397,9 +373,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
count += 1
|
||||
|
||||
def shutdown(self):
|
||||
if self.isFullScreen():
|
||||
self.action_full_screen.trigger()
|
||||
return False
|
||||
self.save_state()
|
||||
return True
|
||||
|
||||
@ -421,6 +394,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
def save_state(self):
|
||||
state = bytearray(self.saveState(self.STATE_VERSION))
|
||||
vprefs['viewer_toolbar_state'] = state
|
||||
if not self.isFullScreen():
|
||||
vprefs.set('viewer_window_geometry', bytearray(self.saveGeometry()))
|
||||
if self.current_book_has_toc:
|
||||
vprefs.set('viewer_toc_isvisible', bool(self.toc.isVisible()))
|
||||
@ -429,6 +403,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
bytearray(self.splitter.saveState()))
|
||||
vprefs['multiplier'] = self.view.multiplier
|
||||
vprefs['in_paged_mode'] = not self.action_toggle_paged_mode.isChecked()
|
||||
vprefs['fullscreen'] = self.isFullScreen()
|
||||
|
||||
def restore_state(self):
|
||||
state = vprefs.get('viewer_toolbar_state', None)
|
||||
@ -449,6 +424,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
True))
|
||||
self.toggle_paged_mode(self.action_toggle_paged_mode.isChecked(),
|
||||
at_start=True)
|
||||
fullscreen = vprefs.get('fullscreen', None)
|
||||
if fullscreen:
|
||||
self.showFullScreen()
|
||||
|
||||
def lookup(self, word):
|
||||
self.dictionary_view.setHtml('<html><body><p>'+ \
|
||||
@ -469,6 +447,11 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
c = config().parse()
|
||||
return c.remember_current_page
|
||||
|
||||
def get_dont_show_cover_opt(self):
|
||||
from calibre.gui2.viewer.documentview import config
|
||||
c = config().parse()
|
||||
return c.dont_show_cover
|
||||
|
||||
def print_book(self):
|
||||
p = Printing(self.iterator, self)
|
||||
p.start_print()
|
||||
@ -477,7 +460,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
p = Printing(self.iterator, self)
|
||||
p.start_preview()
|
||||
|
||||
def toggle_fullscreen(self, x):
|
||||
def toggle_fullscreen(self):
|
||||
if self.isFullScreen():
|
||||
self.showNormal()
|
||||
else:
|
||||
@ -485,9 +468,12 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
|
||||
def showFullScreen(self):
|
||||
self.view.document.page_position.save()
|
||||
self.view.document.switch_to_fullscreen_mode()
|
||||
self.window_mode_changed = 'fullscreen'
|
||||
self.was_maximized = super(EbookViewer, self).isMaximized()
|
||||
self.tool_bar.setVisible(False)
|
||||
self.tool_bar2.setVisible(False)
|
||||
self.action_full_screen.setChecked(True)
|
||||
if not self.view.document.fullscreen_scrollbar:
|
||||
self.vertical_scrollbar.setVisible(False)
|
||||
self.frame.layout().setSpacing(0)
|
||||
@ -500,26 +486,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
|
||||
super(EbookViewer, self).showFullScreen()
|
||||
|
||||
def show_full_screen_label(self):
|
||||
f = self.full_screen_label
|
||||
self.esc_full_screen_action.setEnabled(True)
|
||||
f.setVisible(True)
|
||||
height = 200
|
||||
width = int(0.7*self.view.width())
|
||||
f.resize(width, height)
|
||||
f.move((self.view.width() - width)//2, (self.view.height()-height)//2)
|
||||
a = self.full_screen_label_anim
|
||||
a.setDuration(500)
|
||||
a.setStartValue(QSize(width, 0))
|
||||
a.setEndValue(QSize(width, height))
|
||||
a.start()
|
||||
QTimer.singleShot(3500, self.full_screen_label.hide)
|
||||
self.view.document.switch_to_fullscreen_mode()
|
||||
if self.view.document.fullscreen_clock:
|
||||
self.show_clock()
|
||||
if self.view.document.fullscreen_pos:
|
||||
self.show_pos_label()
|
||||
|
||||
def show_clock(self):
|
||||
self.clock_label.setVisible(True)
|
||||
self.clock_label.setText(QTime(22, 33,
|
||||
@ -559,6 +525,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
|
||||
def showNormal(self):
|
||||
self.view.document.page_position.save()
|
||||
self.view.document.switch_to_window_mode()
|
||||
self.clock_label.setVisible(False)
|
||||
self.pos_label.setVisible(False)
|
||||
self.frame.setFrameStyle(self.original_frame_style)
|
||||
@ -566,23 +533,23 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.clock_timer.stop()
|
||||
self.vertical_scrollbar.setVisible(True)
|
||||
self.window_mode_changed = 'normal'
|
||||
self.esc_full_screen_action.setEnabled(False)
|
||||
self.action_full_screen.setChecked(False)
|
||||
self.tool_bar.setVisible(True)
|
||||
self.tool_bar2.setVisible(True)
|
||||
self.full_screen_label.setVisible(False)
|
||||
if hasattr(self, '_original_frame_margins'):
|
||||
om = self._original_frame_margins
|
||||
self.centralwidget.layout().setContentsMargins(om[0])
|
||||
self.frame.layout().setContentsMargins(om[1])
|
||||
if self.was_maximized:
|
||||
super(EbookViewer, self).showMaximized()
|
||||
else:
|
||||
super(EbookViewer, self).showNormal()
|
||||
|
||||
def handle_window_mode_toggle(self):
|
||||
if self.window_mode_changed:
|
||||
fs = self.window_mode_changed == 'fullscreen'
|
||||
self.window_mode_changed = None
|
||||
if fs:
|
||||
self.show_full_screen_label()
|
||||
else:
|
||||
if not fs:
|
||||
self.view.document.switch_to_window_mode()
|
||||
self.view.document.page_position.restore()
|
||||
self.scrolled(self.view.scroll_fraction)
|
||||
@ -634,7 +601,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
if self.selected_text:
|
||||
QApplication.clipboard().setText(self.selected_text)
|
||||
|
||||
def back(self, x):
|
||||
def back(self):
|
||||
pos = self.history.back(self.pos.value())
|
||||
if pos is not None:
|
||||
self.goto_page(pos)
|
||||
@ -643,7 +610,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
num = self.pos.value()
|
||||
self.goto_page(num)
|
||||
|
||||
def forward(self, x):
|
||||
def forward(self):
|
||||
pos = self.history.forward()
|
||||
if pos is not None:
|
||||
self.goto_page(pos)
|
||||
@ -657,6 +624,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
def goto_page(self, new_page, loaded_check=True):
|
||||
if self.current_page is not None or not loaded_check:
|
||||
for page in self.iterator.spine:
|
||||
# print "goto_page", new_page, page.start_page, page.max_page
|
||||
if new_page >= page.start_page and new_page <= page.max_page:
|
||||
try:
|
||||
frac = float(new_page-page.start_page)/(page.pages-1)
|
||||
@ -681,13 +649,12 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
|
||||
def font_size_larger(self):
|
||||
self.view.magnify_fonts()
|
||||
self.action_font_size_larger.setEnabled(self.view.multiplier < 3)
|
||||
self.action_font_size_smaller.setEnabled(self.view.multiplier > 0.2)
|
||||
|
||||
def font_size_smaller(self):
|
||||
self.view.shrink_fonts()
|
||||
self.action_font_size_larger.setEnabled(self.view.multiplier < 3)
|
||||
self.action_font_size_smaller.setEnabled(self.view.multiplier > 0.2)
|
||||
|
||||
def font_size_restore(self):
|
||||
self.view.restore_font_size()
|
||||
|
||||
def magnification_changed(self, val):
|
||||
tt = _('Make font size %(which)s\nCurrent magnification: %(mag).1f')
|
||||
@ -695,6 +662,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
tt %dict(which=_('larger'), mag=val))
|
||||
self.action_font_size_smaller.setToolTip(
|
||||
tt %dict(which=_('smaller'), mag=val))
|
||||
self.action_font_size_larger.setEnabled(self.view.multiplier < 3)
|
||||
self.action_font_size_smaller.setEnabled(self.view.multiplier > 0.2)
|
||||
|
||||
def find(self, text, repeat=False, backwards=False):
|
||||
if not text:
|
||||
@ -961,7 +930,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
if self.iterator is not None:
|
||||
self.save_current_position()
|
||||
self.iterator.__exit__()
|
||||
self.iterator = EbookIterator(pathtoebook)
|
||||
self.iterator = EbookIterator(pathtoebook, self.get_dont_show_cover_opt())
|
||||
self.open_progress_indicator(_('Loading ebook...'))
|
||||
worker = Worker(target=partial(self.iterator.__enter__,
|
||||
extract_embedded_fonts_for_qt=True))
|
||||
|
@ -28,7 +28,7 @@ from calibre.ebooks.metadata.book.base import Metadata
|
||||
from calibre.constants import preferred_encoding, iswindows, filesystem_encoding
|
||||
from calibre.ptempfile import (PersistentTemporaryFile,
|
||||
base_dir, SpooledTemporaryFile)
|
||||
from calibre.customize.ui import run_plugins_on_import
|
||||
from calibre.customize.ui import run_plugins_on_import, postimport_plugins
|
||||
from calibre import isbytestring
|
||||
from calibre.utils.filenames import (ascii_filename, samefile,
|
||||
WindowsAtomicFolderMove, hardlink_file)
|
||||
@ -1534,6 +1534,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
self.refresh_ids([id])
|
||||
if notify:
|
||||
self.notify('metadata', [id])
|
||||
postimport_plugins(id, format)
|
||||
return True
|
||||
|
||||
def save_original_format(self, book_id, fmt, notify=True):
|
||||
|
Loading…
x
Reference in New Issue
Block a user