示例#1
0
文件: main.py 项目: davidfor/calibre
    def parsed(self):
        if not self.renderer.aborted and self.renderer.lrf is not None:
            width, height = self.renderer.lrf.device_info.width, self.renderer.lrf.device_info.height
            hdelta = self.tool_bar.height() + 3

            s = QScrollBar(self)
            scrollbar_adjust = min(s.width(), s.height())
            self.graphics_view.resize_for(width + scrollbar_adjust, height + scrollbar_adjust)

            desktop = QCoreApplication.instance().desktop()
            screen_height = desktop.availableGeometry(self).height() - 25
            height = min(screen_height, height + hdelta + scrollbar_adjust)
            self.resize(width + scrollbar_adjust, height)
            self.setWindowTitle(self.renderer.lrf.metadata.title + " - " + __appname__)
            self.document_title = self.renderer.lrf.metadata.title
            if self.opts.profile:
                import cProfile

                lrf = self.renderer.lrf
                cProfile.runctx("self.document.render(lrf)", globals(), locals(), lrf.metadata.title + ".stats")
                print "Stats written to", self.renderer.lrf.metadata.title + ".stats"
            else:
                start = time.time()
                self.document.render(self.renderer.lrf)
                print "Layout time:", time.time() - start, "seconds"
            self.renderer.lrf = None

            self.graphics_view.setScene(self.document)
            self.graphics_view.show()
            self.spin_box.setRange(1, self.document.num_of_pages)
            self.slider.setRange(1, self.document.num_of_pages)
            self.spin_box.setSuffix(" of %d" % (self.document.num_of_pages,))
            self.spin_box.updateGeometry()
            self.stack.setCurrentIndex(0)
            self.graphics_view.setFocus(Qt.OtherFocusReason)
        elif self.renderer.exception is not None:
            exception = self.renderer.exception
            print >> sys.stderr, "Error rendering document"
            print >> sys.stderr, exception
            print >> sys.stderr, self.renderer.formatted_traceback
            msg = (
                u"<p><b>%s</b>: " % (exception.__class__.__name__,)
                + unicode(str(exception), "utf8", "replace")
                + u"</p>"
            )
            msg += u"<p>Failed to render document</p>"
            msg += u"<p>Detailed <b>traceback</b>:<pre>"
            msg += self.renderer.formatted_traceback + "</pre>"
            d = ConversionErrorDialog(self, "Error while rendering file", msg)
            d.exec_()
示例#2
0
 def __init__(self, parent=None, show_open_in_editor=False):
     QWidget.__init__(self, parent)
     self.changes = [[], [], []]
     self.delta = 0
     self.l = l = QHBoxLayout(self)
     self.setLayout(l)
     self.syncpos = 0
     l.setContentsMargins(0, 0, 0, 0), l.setSpacing(0)
     self.view = DiffSplit(self, show_open_in_editor=show_open_in_editor)
     l.addWidget(self.view)
     self.add_diff = self.view.add_diff
     self.scrollbar = QScrollBar(self)
     l.addWidget(self.scrollbar)
     self.syncing = False
     self.bars = []
     self.resize_timer = QTimer(self)
     self.resize_timer.setSingleShot(True)
     self.resize_timer.timeout.connect(self.resize_debounced)
     for i, bar in enumerate((self.scrollbar, self.view.left.verticalScrollBar(), self.view.right.verticalScrollBar())):
         self.bars.append(bar)
         bar.valueChanged[int].connect(partial(self.scrolled, i))
     self.view.left.resized.connect(self.resized)
     for i, v in enumerate((self.view.left, self.view.right, self.view.handle(1))):
         v.wheel_event.connect(self.scrollbar.wheelEvent)
         if i < 2:
             v.next_change.connect(self.next_change)
             v.line_activated.connect(self.line_activated)
             v.scrolled.connect(partial(self.scrolled, i + 1))
示例#3
0
文件: view.py 项目: j-howell/calibre
 def __init__(self, parent=None, show_open_in_editor=False):
     QWidget.__init__(self, parent)
     self.changes = [[], [], []]
     self.delta = 0
     self.l = l = QHBoxLayout(self)
     self.setLayout(l)
     self.syncpos = 0
     l.setContentsMargins(0, 0, 0, 0), l.setSpacing(0)
     self.view = DiffSplit(self, show_open_in_editor=show_open_in_editor)
     l.addWidget(self.view)
     self.add_diff = self.view.add_diff
     self.scrollbar = QScrollBar(self)
     l.addWidget(self.scrollbar)
     self.syncing = False
     self.bars = []
     self.resize_timer = QTimer(self)
     self.resize_timer.setSingleShot(True)
     self.resize_timer.timeout.connect(self.resize_debounced)
     for bar in (self.scrollbar, self.view.left.verticalScrollBar(), self.view.right.verticalScrollBar()):
         self.bars.append(bar)
         bar.scroll_idx = len(self.bars) - 1
         connect_lambda(bar.valueChanged[int], self, lambda self: self.scrolled(self.sender().scroll_idx))
     self.view.left.resized.connect(self.resized)
     for v in (self.view.left, self.view.right, self.view.handle(1)):
         v.wheel_event.connect(self.scrollbar.wheelEvent)
         if v is self.view.left or v is self.view.right:
             v.next_change.connect(self.next_change)
             v.line_activated.connect(self.line_activated)
             connect_lambda(v.scrolled, self,
                     lambda self: self.scrolled(1 if self.sender() is self.view.left else 2))
示例#4
0
文件: main.py 项目: JimmXinu/calibre
    def parsed(self):
        if not self.renderer.aborted and self.renderer.lrf is not None:
            width, height =  self.renderer.lrf.device_info.width, \
                                            self.renderer.lrf.device_info.height
            hdelta = self.tool_bar.height()+3

            s = QScrollBar(self)
            scrollbar_adjust = min(s.width(), s.height())
            self.graphics_view.resize_for(width+scrollbar_adjust, height+scrollbar_adjust)

            desktop = QCoreApplication.instance().desktop()
            screen_height = desktop.availableGeometry(self).height() - 25
            height = min(screen_height, height+hdelta+scrollbar_adjust)
            self.resize(width+scrollbar_adjust, height)
            self.setWindowTitle(self.renderer.lrf.metadata.title + ' - ' + __appname__)
            self.document_title = self.renderer.lrf.metadata.title
            if self.opts.profile:
                import cProfile
                lrf = self.renderer.lrf
                cProfile.runctx('self.document.render(lrf)', globals(), locals(), lrf.metadata.title+'.stats')
                print('Stats written to', self.renderer.lrf.metadata.title+'.stats')
            else:
                start = time.time()
                self.document.render(self.renderer.lrf)
                print('Layout time:', time.time()-start, 'seconds')
            self.renderer.lrf = None

            self.graphics_view.setScene(self.document)
            self.graphics_view.show()
            self.spin_box.setRange(1, self.document.num_of_pages)
            self.slider.setRange(1, self.document.num_of_pages)
            self.spin_box.setSuffix(' of %d'%(self.document.num_of_pages,))
            self.spin_box.updateGeometry()
            self.stack.setCurrentIndex(0)
            self.graphics_view.setFocus(Qt.OtherFocusReason)
        elif self.renderer.exception is not None:
            exception = self.renderer.exception
            print('Error rendering document', file=sys.stderr)
            print(exception, file=sys.stderr)
            print(self.renderer.formatted_traceback, file=sys.stderr)
            msg =  u'<p><b>%s</b>: '%(exception.__class__.__name__,) + as_unicode(exception) + u'</p>'
            msg += u'<p>Failed to render document</p>'
            msg += u'<p>Detailed <b>traceback</b>:<pre>'
            msg += self.renderer.formatted_traceback + '</pre>'
            d = ConversionErrorDialog(self, 'Error while rendering file', msg)
            d.exec_()
示例#5
0
class DiffView(QWidget):  # {{{

    SYNC_POSITION = 0.4
    line_activated = pyqtSignal(object, object, object)

    def __init__(self, parent=None, show_open_in_editor=False):
        QWidget.__init__(self, parent)
        self.changes = [[], [], []]
        self.delta = 0
        self.l = l = QHBoxLayout(self)
        self.setLayout(l)
        self.syncpos = 0
        l.setContentsMargins(0, 0, 0, 0), l.setSpacing(0)
        self.view = DiffSplit(self, show_open_in_editor=show_open_in_editor)
        l.addWidget(self.view)
        self.add_diff = self.view.add_diff
        self.scrollbar = QScrollBar(self)
        l.addWidget(self.scrollbar)
        self.syncing = False
        self.bars = []
        self.resize_timer = QTimer(self)
        self.resize_timer.setSingleShot(True)
        self.resize_timer.timeout.connect(self.resize_debounced)
        for i, bar in enumerate((self.scrollbar, self.view.left.verticalScrollBar(), self.view.right.verticalScrollBar())):
            self.bars.append(bar)
            bar.valueChanged[int].connect(partial(self.scrolled, i))
        self.view.left.resized.connect(self.resized)
        for i, v in enumerate((self.view.left, self.view.right, self.view.handle(1))):
            v.wheel_event.connect(self.scrollbar.wheelEvent)
            if i < 2:
                v.next_change.connect(self.next_change)
                v.line_activated.connect(self.line_activated)
                v.scrolled.connect(partial(self.scrolled, i + 1))

    def next_change(self, delta):
        assert delta in (1, -1)
        position = self.get_position_from_scrollbar(0)
        if position[0] == 'in':
            p = n = position[1]
        else:
            p, n = position[1], position[1] + 1
            if p < 0:
                p = None
            if n >= len(self.changes[0]):
                n = None
        if p == n:
            nc = p + delta
            if nc < 0 or nc >= len(self.changes[0]):
                nc = None
        else:
            nc = {1:n, -1:p}[delta]
        if nc is None:
            self.scrollbar.setValue(0 if delta == -1 else self.scrollbar.maximum())
        else:
            val = self.scrollbar.value()
            self.scroll_to(0, ('in', nc, 0))
            nval = self.scrollbar.value()
            if nval == val:
                nval += 5 * delta
                if 0 <= nval <= self.scrollbar.maximum():
                    self.scrollbar.setValue(nval)

    def resized(self):
        self.resize_timer.start(300)

    def resize_debounced(self):
        self.view.resized()
        self.calculate_length()
        self.adjust_range()
        self.view.handle(1).update()

    def get_position_from_scrollbar(self, which):
        changes = self.changes[which]
        bar = self.bars[which]
        syncpos = self.syncpos + bar.value()
        prev = 0
        for i, (top, bot, kind) in enumerate(changes):
            if syncpos <= bot:
                if top <= syncpos:
                    # syncpos is inside a change
                    try:
                        ratio = float(syncpos - top) / (bot - top)
                    except ZeroDivisionError:
                        ratio = 0
                    return 'in', i, ratio
                else:
                    # syncpos is after the previous change
                    offset = syncpos - prev
                    return 'after', i - 1, offset
            else:
                # syncpos is after the current change
                prev = bot
        offset = syncpos - prev
        return 'after', len(changes) - 1, offset

    def scroll_to(self, which, position):
        changes = self.changes[which]
        bar = self.bars[which]
        val = None
        if position[0] == 'in':
            change_idx, ratio = position[1:]
            start, end = changes[change_idx][:2]
            val = start + int((end - start) * ratio)
        else:
            change_idx, offset = position[1:]
            start = 0 if change_idx < 0 else changes[change_idx][1]
            val = start + offset
        bar.setValue(val - self.syncpos)

    def scrolled(self, which, *args):
        if self.syncing:
            return
        position = self.get_position_from_scrollbar(which)
        with self:
            for x in {0, 1, 2} - {which}:
                self.scroll_to(x, position)
        self.view.handle(1).update()

    def __enter__(self):
        self.syncing = True

    def __exit__(self, *args):
        self.syncing = False

    def clear(self):
        with self:
            self.view.clear()
            self.changes = [[], [], []]
            self.delta = 0
            self.scrollbar.setRange(0, 0)

    def adjust_range(self):
        ls, rs = self.view.left.verticalScrollBar(), self.view.right.verticalScrollBar()
        self.scrollbar.setPageStep(min(ls.pageStep(), rs.pageStep()))
        self.scrollbar.setSingleStep(min(ls.singleStep(), rs.singleStep()))
        self.scrollbar.setRange(0, ls.maximum() + self.delta)
        self.scrollbar.setVisible(self.view.left.blockCount() > ls.pageStep() or self.view.right.blockCount() > rs.pageStep())
        self.syncpos = int(ceil(self.scrollbar.pageStep() * self.SYNC_POSITION))

    def finalize(self):
        self.view.finalize()
        self.changes = [[], [], []]
        self.calculate_length()
        self.adjust_range()

    def calculate_length(self):
        delta = 0
        line_number_changes = ([], [])
        for v, lmap, changes in zip((self.view.left, self.view.right), ({}, {}), line_number_changes):
            b = v.document().firstBlock()
            ebl = v.document().documentLayout().ensureBlockLayout
            last_line_count = 0
            while b.isValid():
                ebl(b)
                lmap[b.blockNumber()] = last_line_count
                last_line_count += b.layout().lineCount()
                b = b.next()
            for top, bot, kind in v.changes:
                changes.append((lmap[top], lmap[bot], kind))

        changes = []
        for (l_top, l_bot, kind), (r_top, r_bot, kind) in zip(*line_number_changes):
            height = max(l_bot - l_top, r_bot - r_top)
            top = delta + l_top
            changes.append((top, top + height, kind))
            delta = top + height - l_bot
        self.changes, self.delta = (changes,) + line_number_changes, delta

    def handle_key(self, ev):
        amount, d = None, 1
        key = ev.key()
        if key in (Qt.Key_Up, Qt.Key_Down, Qt.Key_J, Qt.Key_K):
            amount = self.scrollbar.singleStep()
            if key in (Qt.Key_Up, Qt.Key_K):
                d = -1
        elif key in (Qt.Key_PageUp, Qt.Key_PageDown):
            amount = self.scrollbar.pageStep()
            if key in (Qt.Key_PageUp,):
                d = -1
        elif key in (Qt.Key_Home, Qt.Key_End):
            self.scrollbar.setValue(0 if key == Qt.Key_Home else self.scrollbar.maximum())
            return True
        elif key in (Qt.Key_N, Qt.Key_P):
            self.next_change(1 if key == Qt.Key_N else -1)
            return True

        if amount is not None:
            self.scrollbar.setValue(self.scrollbar.value() + d * amount)
            return True
        return False
示例#6
0
    def __init__(self, debug_javascript):
        MainWindow.__init__(self, None)
        self.setWindowTitle(_('E-book viewer'))
        self.base_window_title = unicode(self.windowTitle())
        self.setObjectName('EbookViewer')
        self.setWindowIcon(QIcon(I('viewer.png')))
        self.setDockOptions(self.AnimatedDocks | self.AllowTabbedDocks)

        self.centralwidget = c = QWidget(self)
        c.setObjectName('centralwidget')
        self.setCentralWidget(c)
        self.central_layout = cl = QGridLayout(c)
        cl.setSpacing(0)
        c.setLayout(cl), cl.setContentsMargins(0, 0, 0, 0)

        self.view = v = DocumentView(self)
        v.setMinimumSize(100, 100)
        self.view.initialize_view(debug_javascript)
        v.setObjectName('view')
        cl.addWidget(v)

        self.vertical_scrollbar = vs = QScrollBar(c)
        vs.setOrientation(Qt.Vertical), vs.setObjectName("vertical_scrollbar")
        cl.addWidget(vs, 0, 1, 2, 1)

        self.horizontal_scrollbar = hs = QScrollBar(c)
        hs.setOrientation(
            Qt.Horizontal), hs.setObjectName("horizontal_scrollbar")
        cl.addWidget(hs, 1, 0, 1, 1)

        self.tool_bar = tb = ToolBar(self)
        tb.setObjectName('tool_bar'), tb.setIconSize(QSize(32, 32))
        self.addToolBar(Qt.LeftToolBarArea, tb)

        self.tool_bar2 = tb2 = QToolBar(self)
        tb2.setObjectName('tool_bar2')
        self.addToolBar(Qt.TopToolBarArea, tb2)
        self.tool_bar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.tool_bar2.setContextMenuPolicy(Qt.PreventContextMenu)

        self.pos = DoubleSpinBox()
        self.pos.setDecimals(1)
        self.pos.setSuffix('/' + _('Unknown') + '     ')
        self.pos.setMinimum(1.)
        self.tool_bar2.addWidget(self.pos)
        self.tool_bar2.addSeparator()
        self.reference = Reference()
        self.tool_bar2.addWidget(self.reference)
        self.tool_bar2.addSeparator()
        self.search = SearchBox2(self)
        self.search.setMinimumContentsLength(20)
        self.search.initialize('viewer_search_history')
        self.search.setToolTip(_('Search for text in book'))
        self.search.setMinimumWidth(200)
        self.tool_bar2.addWidget(self.search)

        self.toc_dock = d = QDockWidget(_('Table of Contents'), self)
        d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.toc_container = w = QWidget(self)
        w.l = QVBoxLayout(w)
        self.toc = TOCView(w)
        self.toc_search = TOCSearch(self.toc, parent=w)
        w.l.addWidget(self.toc), w.l.addWidget(
            self.toc_search), w.l.setContentsMargins(0, 0, 0, 0)
        d.setObjectName('toc-dock')
        d.setWidget(w)
        d.close()  # starts out hidden
        self.addDockWidget(Qt.LeftDockWidgetArea, d)
        d.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.bookmarks_dock = d = QDockWidget(_('Bookmarks'), self)
        d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.bookmarks = BookmarkManager(self)
        d.setObjectName('bookmarks-dock')
        d.setWidget(self.bookmarks)
        d.close()  # starts out hidden
        self.addDockWidget(Qt.RightDockWidgetArea, d)
        d.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.footnotes_dock = d = QDockWidget(_('Footnotes'), self)
        d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.footnotes_view = FootnotesView(self)
        self.footnotes_view.follow_link.connect(self.view.follow_footnote_link)
        self.footnotes_view.close_view.connect(d.close)
        self.view.footnotes.set_footnotes_view(self.footnotes_view)
        d.setObjectName('footnotes-dock')
        d.setWidget(self.footnotes_view)
        d.close()  # starts out hidden
        self.addDockWidget(Qt.BottomDockWidgetArea, d)
        d.setAllowedAreas(Qt.BottomDockWidgetArea | Qt.TopDockWidgetArea
                          | Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.create_actions()
        self.themes_menu.aboutToShow.connect(self.themes_menu_shown,
                                             type=Qt.QueuedConnection)

        self.metadata = Metadata(self.centralwidget)
        self.history = History(self.action_back, self.action_forward)

        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.centralWidget())
        self.full_screen_label.setVisible(False)
        self.full_screen_label.final_height = 200
        self.full_screen_label.setFocusPolicy(Qt.NoFocus)
        self.full_screen_label.setStyleSheet('''
        QLabel {
            text-align: center;
            background-color: white;
            color: black;
            border-width: 1px;
            border-style: solid;
            border-radius: 20px;
        }
        ''')
        self.clock_label = QLabel('99:99', self.centralWidget())
        self.clock_label.setVisible(False)
        self.clock_label.setFocusPolicy(Qt.NoFocus)
        self.info_label_style = '''
            QLabel {
                text-align: center;
                border-width: 1px;
                border-style: solid;
                border-radius: 8px;
                background-color: %s;
                color: %s;
                font-family: monospace;
                font-size: larger;
                padding: 5px;
        }'''
        self.pos_label = QLabel('2000/4000', self.centralWidget())
        self.pos_label.setVisible(False)
        self.pos_label.setFocusPolicy(Qt.NoFocus)

        self.resize(653, 746)
示例#7
0
class DiffView(QWidget):  # {{{

    SYNC_POSITION = 0.4
    line_activated = pyqtSignal(object, object, object)

    def __init__(self, parent=None, show_open_in_editor=False):
        QWidget.__init__(self, parent)
        self.changes = [[], [], []]
        self.delta = 0
        self.l = l = QHBoxLayout(self)
        self.setLayout(l)
        self.syncpos = 0
        l.setContentsMargins(0, 0, 0, 0), l.setSpacing(0)
        self.view = DiffSplit(self, show_open_in_editor=show_open_in_editor)
        l.addWidget(self.view)
        self.add_diff = self.view.add_diff
        self.scrollbar = QScrollBar(self)
        l.addWidget(self.scrollbar)
        self.syncing = False
        self.bars = []
        self.resize_timer = QTimer(self)
        self.resize_timer.setSingleShot(True)
        self.resize_timer.timeout.connect(self.resize_debounced)
        for bar in (self.scrollbar, self.view.left.verticalScrollBar(), self.view.right.verticalScrollBar()):
            self.bars.append(bar)
            bar.scroll_idx = len(self.bars) - 1
            connect_lambda(bar.valueChanged[int], self, lambda self: self.scrolled(self.sender().scroll_idx))
        self.view.left.resized.connect(self.resized)
        for v in (self.view.left, self.view.right, self.view.handle(1)):
            v.wheel_event.connect(self.scrollbar.wheelEvent)
            if v is self.view.left or v is self.view.right:
                v.next_change.connect(self.next_change)
                v.line_activated.connect(self.line_activated)
                connect_lambda(v.scrolled, self,
                        lambda self: self.scrolled(1 if self.sender() is self.view.left else 2))

    def next_change(self, delta):
        assert delta in (1, -1)
        position = self.get_position_from_scrollbar(0)
        if position[0] == 'in':
            p = n = position[1]
        else:
            p, n = position[1], position[1] + 1
            if p < 0:
                p = None
            if n >= len(self.changes[0]):
                n = None
        if p == n:
            nc = p + delta
            if nc < 0 or nc >= len(self.changes[0]):
                nc = None
        else:
            nc = {1:n, -1:p}[delta]
        if nc is None:
            self.scrollbar.setValue(0 if delta == -1 else self.scrollbar.maximum())
        else:
            val = self.scrollbar.value()
            self.scroll_to(0, ('in', nc, 0))
            nval = self.scrollbar.value()
            if nval == val:
                nval += 5 * delta
                if 0 <= nval <= self.scrollbar.maximum():
                    self.scrollbar.setValue(nval)

    def resized(self):
        self.resize_timer.start(300)

    def resize_debounced(self):
        self.view.resized()
        self.calculate_length()
        self.adjust_range()
        self.view.handle(1).update()

    def get_position_from_scrollbar(self, which):
        changes = self.changes[which]
        bar = self.bars[which]
        syncpos = self.syncpos + bar.value()
        prev = 0
        for i, (top, bot, kind) in enumerate(changes):
            if syncpos <= bot:
                if top <= syncpos:
                    # syncpos is inside a change
                    try:
                        ratio = float(syncpos - top) / (bot - top)
                    except ZeroDivisionError:
                        ratio = 0
                    return 'in', i, ratio
                else:
                    # syncpos is after the previous change
                    offset = syncpos - prev
                    return 'after', i - 1, offset
            else:
                # syncpos is after the current change
                prev = bot
        offset = syncpos - prev
        return 'after', len(changes) - 1, offset

    def scroll_to(self, which, position):
        changes = self.changes[which]
        bar = self.bars[which]
        val = None
        if position[0] == 'in':
            change_idx, ratio = position[1:]
            start, end = changes[change_idx][:2]
            val = start + int((end - start) * ratio)
        else:
            change_idx, offset = position[1:]
            start = 0 if change_idx < 0 else changes[change_idx][1]
            val = start + offset
        bar.setValue(val - self.syncpos)

    def scrolled(self, which, *args):
        if self.syncing:
            return
        position = self.get_position_from_scrollbar(which)
        with self:
            for x in {0, 1, 2} - {which}:
                self.scroll_to(x, position)
        self.view.handle(1).update()

    def __enter__(self):
        self.syncing = True

    def __exit__(self, *args):
        self.syncing = False

    def clear(self):
        with self:
            self.view.clear()
            self.changes = [[], [], []]
            self.delta = 0
            self.scrollbar.setRange(0, 0)

    def adjust_range(self):
        ls, rs = self.view.left.verticalScrollBar(), self.view.right.verticalScrollBar()
        self.scrollbar.setPageStep(min(ls.pageStep(), rs.pageStep()))
        self.scrollbar.setSingleStep(min(ls.singleStep(), rs.singleStep()))
        self.scrollbar.setRange(0, ls.maximum() + self.delta)
        self.scrollbar.setVisible(self.view.left.document().lineCount() > ls.pageStep() or self.view.right.document().lineCount() > rs.pageStep())
        self.syncpos = int(ceil(self.scrollbar.pageStep() * self.SYNC_POSITION))

    def finalize(self):
        self.view.finalize()
        self.changes = [[], [], []]
        self.calculate_length()
        self.adjust_range()

    def calculate_length(self):
        delta = 0
        line_number_changes = ([], [])
        for v, lmap, changes in zip((self.view.left, self.view.right), ({}, {}), line_number_changes):
            b = v.document().firstBlock()
            ebl = v.document().documentLayout().ensureBlockLayout
            last_line_count = 0
            while b.isValid():
                ebl(b)
                lmap[b.blockNumber()] = last_line_count
                last_line_count += b.layout().lineCount()
                b = b.next()
            for top, bot, kind in v.changes:
                changes.append((lmap[top], lmap[bot], kind))

        changes = []
        for (l_top, l_bot, kind), (r_top, r_bot, kind) in zip(*line_number_changes):
            height = max(l_bot - l_top, r_bot - r_top)
            top = delta + l_top
            changes.append((top, top + height, kind))
            delta = top + height - l_bot
        self.changes, self.delta = (changes,) + line_number_changes, delta

    def handle_key(self, ev):
        amount, d = None, 1
        key = ev.key()
        if key in (Qt.Key.Key_Up, Qt.Key.Key_Down, Qt.Key.Key_J, Qt.Key.Key_K):
            amount = self.scrollbar.singleStep()
            if key in (Qt.Key.Key_Up, Qt.Key.Key_K):
                d = -1
        elif key in (Qt.Key.Key_PageUp, Qt.Key.Key_PageDown):
            amount = self.scrollbar.pageStep()
            if key in (Qt.Key.Key_PageUp,):
                d = -1
        elif key in (Qt.Key.Key_Home, Qt.Key.Key_End):
            self.scrollbar.setValue(0 if key == Qt.Key.Key_Home else self.scrollbar.maximum())
            return True
        elif key in (Qt.Key.Key_N, Qt.Key.Key_P):
            self.next_change(1 if key == Qt.Key.Key_N else -1)
            return True

        if amount is not None:
            self.scrollbar.setValue(self.scrollbar.value() + d * amount)
            return True
        return False
示例#8
0
文件: ui.py 项目: zieglerm/calibre
 def paintEvent(self, ev):
     if self.isEnabled():
         return QScrollBar.paintEvent(self, ev)