From b052f6ed686df4ae3410c46c78e596173f5653cf Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Apr 2014 14:44:47 +0530 Subject: [PATCH] Port use of QVariant in the viewer, the viewer now basically works --- setup/qt5-migrate.py | 4 ++- src/calibre/gui2/shortcuts.py | 42 +++++++++++----------- src/calibre/gui2/viewer/bookmarkmanager.py | 4 +-- src/calibre/gui2/viewer/config.py | 6 ++-- src/calibre/gui2/viewer/documentview.py | 27 +++++++------- src/calibre/gui2/viewer/image_popup.py | 2 +- src/calibre/gui2/viewer/position.py | 15 ++++---- src/calibre/gui2/viewer/printing.py | 10 ++++-- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/setup/qt5-migrate.py b/setup/qt5-migrate.py index ce372a841c..8c279abe5b 100644 --- a/setup/qt5-migrate.py +++ b/setup/qt5-migrate.py @@ -34,7 +34,9 @@ def all_py_files(): def detect_qvariant(): count = 0 pat = re.compile(b'|'.join(br'QVariant NONE toInt toBool toString\(\) toPyObject canConvert toBitArray toByteArray toHash toFloat toMap toLine toPoint toReal toRect toTime toUInt toUrl'.split())) # noqa - exclusions = {} + exclusions = { + 'src/calibre/gui2/viewer/gestures.py': {'toPoint'}, + } for path in all_py_files(): if os.path.basename(path) in { 'BeautifulSoup.py', 'icu.py', 'smtp.py', 'Zeroconf.py', 'date.py', 'apsw_shell.py', } or 'pylrs' in path: diff --git a/src/calibre/gui2/shortcuts.py b/src/calibre/gui2/shortcuts.py index d05818cc27..45ae55b92d 100644 --- a/src/calibre/gui2/shortcuts.py +++ b/src/calibre/gui2/shortcuts.py @@ -10,9 +10,9 @@ from functools import partial from PyQt5.Qt import QAbstractListModel, Qt, QKeySequence, QListView, \ QHBoxLayout, QWidget, QApplication, QStyledItemDelegate, QStyle, \ - QVariant, QTextDocument, QRectF, QFrame, QSize, QFont, QKeyEvent + QTextDocument, QRectF, QFrame, QSize, QFont, QKeyEvent -from calibre.gui2 import NONE, error_dialog +from calibre.gui2 import error_dialog from calibre.utils.config import XMLConfig from calibre.utils.icu import sort_key from calibre.gui2.shortcuts_ui import Ui_Frame @@ -72,13 +72,13 @@ class Customize(QFrame, Ui_Frame): font = QFont() button.setFont(font) sequence = QKeySequence(code|(int(ev.modifiers())&~Qt.KeypadModifier)) - button.setText(sequence.toString()) + button.setText(sequence.toString(QKeySequence.NativeText)) self.capture = 0 setattr(self, 'shortcut%d'%which, sequence) dup_desc = self.dup_check(sequence, self.key) if dup_desc is not None: error_dialog(self, _('Already assigned'), - unicode(sequence.toString()) + ' ' + + unicode(sequence.toString(QKeySequence.NativeText)) + ' ' + _('already assigned to') + ' ' + dup_desc, show=True) self.clear_clicked(which=which) @@ -92,7 +92,7 @@ class Delegate(QStyledItemDelegate): def to_doc(self, index): doc = QTextDocument() - doc.setHtml(index.data().toString()) + doc.setHtml(index.data()) return doc def editing_done(self, editor, hint): @@ -128,14 +128,14 @@ class Delegate(QStyledItemDelegate): return w def setEditorData(self, editor, index): - defs = index.data(DEFAULTS).toPyObject() + defs = index.data(DEFAULTS) defs = _(' or ').join([unicode(x.toString(x.NativeText)) for x in defs]) - editor.key = unicode(index.data(KEY).toString()) + editor.key = unicode(index.data(KEY)) editor.default_shortcuts.setText(_('&Default') + ': %s' % defs) editor.default_shortcuts.setChecked(True) editor.header.setText('%s: %s'%(_('Customize shortcuts for'), - unicode(index.data(DESCRIPTION).toString()))) - custom = index.data(CUSTOM).toPyObject() + unicode(index.data(DESCRIPTION)))) + custom = index.data(CUSTOM) if custom: editor.custom.setChecked(True) for x in (0, 1): @@ -212,38 +212,36 @@ class Shortcuts(QAbstractListModel): return [unicode(x.toString(x.NativeText)) for x in self.get_sequences(key)] - def data(self, index, role): row = index.row() if row < 0 or row >= len(self.order): - return NONE + return None key = self.order[row] if role == Qt.DisplayRole: - return QVariant(self.TEMPLATE.format(self.descriptions[key], - _(' or ').join(self.get_shortcuts(key)), _('Keys'))) + return self.TEMPLATE.format(self.descriptions[key], + _(' or ').join(self.get_shortcuts(key)), _('Keys')) if role == Qt.ToolTipRole: - return QVariant(_('Double click to change')) + return _('Double click to change') if role == DEFAULTS: - return QVariant(self.sequences[key]) + return self.sequences[key] if role == DESCRIPTION: - return QVariant(self.descriptions[key]) + return self.descriptions[key] if role == CUSTOM: if key in self.custom: - return QVariant(self.custom[key]) + return self.custom[key] else: - return QVariant([]) + return [] if role == KEY: - return QVariant(key) - return NONE + return key + return None def set_data(self, index, custom): key = self.order[index.row()] if custom: - self.custom[key] = [unicode(x.toString()) for x in custom] + self.custom[key] = [unicode(x.toString(QKeySequence.PortableText)) for x in custom] elif key in self.custom: del self.custom[key] - def flags(self, index): if not index.isValid(): return Qt.ItemIsEnabled diff --git a/src/calibre/gui2/viewer/bookmarkmanager.py b/src/calibre/gui2/viewer/bookmarkmanager.py index c78dcebaa5..84e23a8752 100644 --- a/src/calibre/gui2/viewer/bookmarkmanager.py +++ b/src/calibre/gui2/viewer/bookmarkmanager.py @@ -145,7 +145,7 @@ class BookmarkManager(QWidget): def item_changed(self, item): self.bookmarks_list.blockSignals(True) - title = unicode(item.data(Qt.DisplayRole).toString()) + title = unicode(item.data(Qt.DisplayRole)) if not title: title = _('Unknown') item.setData(Qt.DisplayRole, title) @@ -186,7 +186,7 @@ class BookmarkManager(QWidget): return bytearray(cPickle.dumps(bm, -1)) def item_to_bm(self, item): - return cPickle.loads(bytes(item.data(Qt.UserRole).toPyObject())) + return cPickle.loads(bytes(item.data(Qt.UserRole))) def get_bookmarks(self): return list(self) diff --git a/src/calibre/gui2/viewer/config.py b/src/calibre/gui2/viewer/config.py index bec9718bb0..69165b3ee5 100644 --- a/src/calibre/gui2/viewer/config.py +++ b/src/calibre/gui2/viewer/config.py @@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en' import zipfile from functools import partial -from PyQt5.Qt import (QFont, QVariant, QDialog, Qt, QColor, QColorDialog, +from PyQt5.Qt import (QFont, QDialog, Qt, QColor, QColorDialog, QMenu, QInputDialog) from calibre.constants import iswindows, isxp @@ -120,7 +120,7 @@ class ConfigDialog(QDialog, Ui_Dialog): for i in range(len(pats)): pmap[names[i]] = pats[i] for x in sorted(names): - self.hyphenate_default_lang.addItem(x, QVariant(pmap[x])) + self.hyphenate_default_lang.addItem(x, pmap[x]) self.hyphenate_pats = pats self.hyphenate_names = names p = self.tabs.widget(1) @@ -304,7 +304,7 @@ class ConfigDialog(QDialog, Ui_Dialog): float(self.opt_font_mag_step.value())/100.) idx = self.hyphenate_default_lang.currentIndex() c.set('hyphenate_default_lang', - str(self.hyphenate_default_lang.itemData(idx).toString())) + self.hyphenate_default_lang.itemData(idx)) c.set('line_scrolling_stops_on_pagebreaks', self.opt_line_scrolling_stops_on_pagebreaks.isChecked()) c.set('fullscreen_clock', self.opt_fullscreen_clock.isChecked()) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 30750d6750..6a263459e6 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -145,7 +145,7 @@ class Document(QWebPage): # {{{ q = unicode(q) hyphenated_q = self.javascript( 'hyphenate_text(%s, "%s")' % (json.dumps(q, ensure_ascii=False), self.loaded_lang), typ='string') - if QWebPage.findText(self, hyphenated_q, flags): + if hyphenated_q and QWebPage.findText(self, hyphenated_q, flags): return True return QWebPage.findText(self, q, flags) @@ -351,17 +351,19 @@ class Document(QWebPage): # {{{ def javascript(self, string, typ=None): ans = self.mainFrame().evaluateJavaScript(string) if typ in {'int', int}: - ans = ans.toInt() - if ans[1]: - return ans[0] - return 0 + try: + return int(ans) + except (TypeError, ValueError): + return 0 if typ in {'float', float}: - ans = ans.toReal() - return ans[0] if ans[1] else 0.0 + try: + return float(ans) + except (TypeError, ValueError): + return 0.0 if typ == 'string': - return unicode(ans.toString()) + return ans or u'' if typ in {bool, 'bool'}: - return ans.toBool() + return bool(ans) return ans def javaScriptConsoleMessage(self, msg, lineno, msgid): @@ -386,8 +388,9 @@ class Document(QWebPage): # {{{ self.javascript('window.paged_display.jump_to_anchor("%s")'%anchor) def element_ypos(self, elem): - ans, ok = elem.evaluateJavaScript('$(this).offset().top').toInt() - if not ok: + try: + ans = int(elem.evaluateJavaScript('$(this).offset().top')) + except (TypeError, ValueError): raise ValueError('No ypos found') return ans @@ -482,7 +485,7 @@ class Document(QWebPage): # {{{ def extract_node(self): return unicode(self.mainFrame().evaluateJavaScript( - 'window.calibre_extract.extract()').toString()) + 'window.calibre_extract.extract()')) # }}} diff --git a/src/calibre/gui2/viewer/image_popup.py b/src/calibre/gui2/viewer/image_popup.py index 6219852f81..1c3756e50a 100644 --- a/src/calibre/gui2/viewer/image_popup.py +++ b/src/calibre/gui2/viewer/image_popup.py @@ -98,7 +98,7 @@ class ImageView(QDialog): if geom is not None: self.restoreGeometry(geom) try: - self.current_image_name = unicode(self.current_url.toString()).rpartition('/')[-1] + self.current_image_name = unicode(self.current_url.toString(QUrl.None)).rpartition('/')[-1] except AttributeError: self.current_image_name = self.current_url title = _('View Image: %s')%self.current_image_name diff --git a/src/calibre/gui2/viewer/position.py b/src/calibre/gui2/viewer/position.py index ddff91794e..c7f1b03b7e 100644 --- a/src/calibre/gui2/viewer/position.py +++ b/src/calibre/gui2/viewer/position.py @@ -16,8 +16,7 @@ class PagePosition(object): @property def viewport_cfi(self): - ans = None - res = self.document.mainFrame().evaluateJavaScript(''' + ans = self.document.mainFrame().evaluateJavaScript(''' ans = 'undefined'; if (window.paged_display) { ans = window.paged_display.current_cfi(); @@ -25,10 +24,8 @@ class PagePosition(object): } ans; ''') - if res.isValid() and not res.isNull() and res.type() == res.String: - c = unicode(res.toString()) - if c != 'undefined': - ans = c + if ans in {'', 'undefined'}: + ans = None return ans def scroll_to_cfi(self, cfi): @@ -51,11 +48,13 @@ class PagePosition(object): self.restore() def save(self, overwrite=True): - if not overwrite and self._cpos is not None: return + if not overwrite and self._cpos is not None: + return self._cpos = self.current_pos def restore(self): - if self._cpos is None: return + if self._cpos is None: + return self.to_pos(self._cpos) self._cpos = None diff --git a/src/calibre/gui2/viewer/printing.py b/src/calibre/gui2/viewer/printing.py index f9a0b4494a..87661e6b1d 100644 --- a/src/calibre/gui2/viewer/printing.py +++ b/src/calibre/gui2/viewer/printing.py @@ -82,9 +82,13 @@ class Printing(QObject): printer.newPage() first = False self.mf.render(painter) - nsl = evaljs('paged_display.next_screen_location()').toInt() - if not nsl[1] or nsl[0] <= 0: break - evaljs('window.scrollTo(%d, 0)'%nsl[0]) + try: + nsl = int(evaljs('paged_display.next_screen_location()')) + except (TypeError, ValueError): + break + if nsl <= 0: + break + evaljs('window.scrollTo(%d, 0)'%nsl) painter.end()