class TOCViewer(QWidget): navigate_requested = pyqtSignal(object, object) def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QGridLayout(self) self.setLayout(l) l.setContentsMargins(0, 0, 0, 0) self.is_visible = False self.view = QTreeWidget(self) self.delegate = Delegate(self.view) self.view.setItemDelegate(self.delegate) self.view.setHeaderHidden(True) self.view.setAnimated(True) self.view.setContextMenuPolicy(Qt.CustomContextMenu) self.view.customContextMenuRequested.connect(self.show_context_menu, type=Qt.QueuedConnection) self.view.itemActivated.connect(self.emit_navigate) self.view.itemPressed.connect(self.item_pressed) pi = plugins['progress_indicator'][0] if hasattr(pi, 'set_no_activate_on_click'): pi.set_no_activate_on_click(self.view) self.view.itemDoubleClicked.connect(self.emit_navigate) l.addWidget(self.view) self.refresh_action = QAction(QIcon(I('view-refresh.png')), _('&Refresh'), self) self.refresh_action.triggered.connect(self.build) def item_pressed(self, item): if QApplication.mouseButtons() & Qt.LeftButton: QTimer.singleShot(0, self.emit_navigate) def show_context_menu(self, pos): menu = QMenu(self) menu.addAction(actions['edit-toc']) menu.addAction(_('&Expand all'), self.view.expandAll) menu.addAction(_('&Collapse all'), self.view.collapseAll) menu.addAction(self.refresh_action) menu.exec_(self.view.mapToGlobal(pos)) def iteritems(self, parent=None): if parent is None: parent = self.invisibleRootItem() for i in xrange(parent.childCount()): child = parent.child(i) yield child for gc in self.iteritems(parent=child): yield gc def emit_navigate(self, *args): item = self.view.currentItem() if item is not None: dest = unicode(item.data(0, DEST_ROLE).toString()) frag = unicode(item.data(0, FRAG_ROLE).toString()) if not frag: frag = TOP self.navigate_requested.emit(dest, frag) def build(self): c = current_container() if c is None: return toc = get_toc(c, verify_destinations=False) def process_node(toc, parent): for child in toc: node = QTreeWidgetItem(parent) node.setText(0, child.title or '') node.setData(0, DEST_ROLE, child.dest or '') node.setData(0, FRAG_ROLE, child.frag or '') tt = _('File: {0}\nAnchor: {1}').format( child.dest or '', child.frag or _('Top of file')) node.setData(0, Qt.ToolTipRole, tt) process_node(child, node) self.view.clear() process_node(toc, self.view.invisibleRootItem()) def visibility_changed(self, visible): self.is_visible = visible if visible: self.build() def update_if_visible(self): if self.is_visible: self.build()
class TOCViewer(QWidget): navigate_requested = pyqtSignal(object, object) refresh_requested = pyqtSignal() def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QGridLayout(self) self.setLayout(l) l.setContentsMargins(0, 0, 0, 0) self.view = QTreeWidget(self) self.delegate = Delegate(self.view) self.view.setItemDelegate(self.delegate) self.view.setHeaderHidden(True) self.view.setAnimated(True) self.view.setContextMenuPolicy(Qt.CustomContextMenu) self.view.customContextMenuRequested.connect(self.show_context_menu, type=Qt.QueuedConnection) self.view.itemActivated.connect(self.emit_navigate) self.view.itemPressed.connect(self.item_pressed) pi = plugins['progress_indicator'][0] if hasattr(pi, 'set_no_activate_on_click'): pi.set_no_activate_on_click(self.view) self.view.itemDoubleClicked.connect(self.emit_navigate) l.addWidget(self.view) self.refresh_action = QAction(QIcon(I('view-refresh.png')), _('&Refresh'), self) self.refresh_action.triggered.connect(self.refresh) self.refresh_timer = t = QTimer(self) t.setInterval(1000), t.setSingleShot(True) t.timeout.connect(self.auto_refresh) self.toc_name = None self.currently_editing = None def start_refresh_timer(self, name): if self.isVisible() and self.toc_name == name: self.refresh_timer.start() def auto_refresh(self): if self.isVisible(): try: self.refresh() except Exception: # ignore errors during live refresh of the toc import traceback traceback.print_exc() def refresh(self): self.refresh_requested.emit() # Give boss a chance to commit dirty editors to the container self.build() def item_pressed(self, item): if QApplication.mouseButtons() & Qt.LeftButton: QTimer.singleShot(0, self.emit_navigate) def show_context_menu(self, pos): menu = QMenu(self) menu.addAction(actions['edit-toc']) menu.addAction(_('&Expand all'), self.view.expandAll) menu.addAction(_('&Collapse all'), self.view.collapseAll) menu.addAction(self.refresh_action) menu.exec_(self.view.mapToGlobal(pos)) def iteritems(self, parent=None): if parent is None: parent = self.invisibleRootItem() for i in xrange(parent.childCount()): child = parent.child(i) yield child for gc in self.iteritems(parent=child): yield gc def emit_navigate(self, *args): item = self.view.currentItem() if item is not None: dest = unicode(item.data(0, DEST_ROLE).toString()) frag = unicode(item.data(0, FRAG_ROLE).toString()) if not frag: frag = TOP self.navigate_requested.emit(dest, frag) def build(self): c = current_container() if c is None: return toc = get_toc(c, verify_destinations=False) self.toc_name = getattr(toc, 'toc_file_name', None) def process_node(toc, parent): for child in toc: node = QTreeWidgetItem(parent) node.setText(0, child.title or '') node.setData(0, DEST_ROLE, child.dest or '') node.setData(0, FRAG_ROLE, child.frag or '') tt = _('File: {0}\nAnchor: {1}').format( child.dest or '', child.frag or _('Top of file')) node.setData(0, Qt.ToolTipRole, tt) process_node(child, node) self.view.clear() process_node(toc, self.view.invisibleRootItem()) def showEvent(self, ev): if self.toc_name is None or not ev.spontaneous(): self.build() return super(TOCViewer, self).showEvent(ev) def update_if_visible(self): if self.isVisible(): self.build()
class TOCViewer(QWidget): navigate_requested = pyqtSignal(object, object) refresh_requested = pyqtSignal() def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QGridLayout(self) self.setLayout(l) l.setContentsMargins(0, 0, 0, 0) self.view = QTreeWidget(self) self.delegate = Delegate(self.view) self.view.setItemDelegate(self.delegate) self.view.setHeaderHidden(True) self.view.setAnimated(True) self.view.setContextMenuPolicy(Qt.CustomContextMenu) self.view.customContextMenuRequested.connect(self.show_context_menu, type=Qt.QueuedConnection) self.view.itemActivated.connect(self.emit_navigate) self.view.itemPressed.connect(self.item_pressed) pi = plugins['progress_indicator'][0] if hasattr(pi, 'set_no_activate_on_click'): pi.set_no_activate_on_click(self.view) self.view.itemDoubleClicked.connect(self.emit_navigate) l.addWidget(self.view) self.refresh_action = QAction(QIcon(I('view-refresh.png')), _('&Refresh'), self) self.refresh_action.triggered.connect(self.refresh) self.refresh_timer = t = QTimer(self) t.setInterval(1000), t.setSingleShot(True) t.timeout.connect(self.auto_refresh) self.toc_name = None self.currently_editing = None def start_refresh_timer(self, name): if self.isVisible() and self.toc_name == name: self.refresh_timer.start() def auto_refresh(self): if self.isVisible(): try: self.refresh() except Exception: # ignore errors during live refresh of the toc import traceback traceback.print_exc() def refresh(self): self.refresh_requested.emit( ) # Give boss a chance to commit dirty editors to the container self.build() def item_pressed(self, item): if QApplication.mouseButtons() & Qt.LeftButton: QTimer.singleShot(0, self.emit_navigate) def show_context_menu(self, pos): menu = QMenu(self) menu.addAction(actions['edit-toc']) menu.addAction(_('&Expand all'), self.view.expandAll) menu.addAction(_('&Collapse all'), self.view.collapseAll) menu.addAction(self.refresh_action) menu.exec_(self.view.mapToGlobal(pos)) def iteritems(self, parent=None): if parent is None: parent = self.invisibleRootItem() for i in xrange(parent.childCount()): child = parent.child(i) yield child for gc in self.iteritems(parent=child): yield gc def emit_navigate(self, *args): item = self.view.currentItem() if item is not None: dest = unicode(item.data(0, DEST_ROLE).toString()) frag = unicode(item.data(0, FRAG_ROLE).toString()) if not frag: frag = TOP self.navigate_requested.emit(dest, frag) def build(self): c = current_container() if c is None: return toc = get_toc(c, verify_destinations=False) self.toc_name = getattr(toc, 'toc_file_name', None) def process_node(toc, parent): for child in toc: node = QTreeWidgetItem(parent) node.setText(0, child.title or '') node.setData(0, DEST_ROLE, child.dest or '') node.setData(0, FRAG_ROLE, child.frag or '') tt = _('File: {0}\nAnchor: {1}').format( child.dest or '', child.frag or _('Top of file')) node.setData(0, Qt.ToolTipRole, tt) process_node(child, node) self.view.clear() process_node(toc, self.view.invisibleRootItem()) def showEvent(self, ev): if self.toc_name is None or not ev.spontaneous(): self.build() return super(TOCViewer, self).showEvent(ev) def update_if_visible(self): if self.isVisible(): self.build()