diff --git a/qutebrowser/widgets/browser.py b/qutebrowser/widgets/browser.py index 106c439da..8de6a02f2 100644 --- a/qutebrowser/widgets/browser.py +++ b/qutebrowser/widgets/browser.py @@ -67,16 +67,19 @@ class TabbedBrowser(TabWidget): set_cmd_text = pyqtSignal(str) # Set commandline to a given text keypress = pyqtSignal('QKeyEvent') _url_stack = [] # Stack of URLs of closed tabs + _space = None # Space QShortcut + _tabs = None def __init__(self, parent=None): super().__init__(parent) self.currentChanged.connect(lambda idx: self.widget(idx).signal_cache.replay()) - space = QShortcut(self) - space.setKey(Qt.Key_Space) - space.setContext(Qt.WidgetWithChildrenShortcut) - space.activated.connect(lambda: self.cur_scroll_page(0, 1)) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + self._tabs = [] + self._space = QShortcut(self) + self._space.setKey(Qt.Key_Space) + self._space.setContext(Qt.WidgetWithChildrenShortcut) + self._space.activated.connect(lambda: self.cur_scroll_page(0, 1)) def tabopen(self, url): """Open a new tab with a given url. @@ -87,6 +90,7 @@ class TabbedBrowser(TabWidget): logging.debug("Opening {}".format(url)) url = urlutils.qurl(url) tab = BrowserTab(self) + self._tabs.append(tab) self.addTab(tab, urlutils.urlstring(url)) self.setCurrentWidget(tab) tab.linkHovered.connect(self._filter_factory(self.cur_link_hovered)) @@ -149,6 +153,10 @@ class TabbedBrowser(TabWidget): # FIXME maybe we actually should store the webview objects here self._url_stack.append(tab.url()) self.removeTab(idx) + try: + self._tabs.remove(tab) + except ValueError: + pass else: # FIXME pass diff --git a/qutebrowser/widgets/completion.py b/qutebrowser/widgets/completion.py index 07f487ccc..a2320eda7 100644 --- a/qutebrowser/widgets/completion.py +++ b/qutebrowser/widgets/completion.py @@ -226,6 +226,7 @@ class CompletionItemDelegate(QStyledItemDelegate): opt = None style = None painter = None + doc = None def sizeHint(self, option, index): """Override sizeHint of QStyledItemDelegate. @@ -239,11 +240,12 @@ class CompletionItemDelegate(QStyledItemDelegate): return value self.opt = QStyleOptionViewItem(option) self.initStyleOption(self.opt, index) - style = self.opt.widget.style() - doc = self._get_textdoc(index) - docsize = doc.size().toSize() - return style.sizeFromContents(QStyle.CT_ItemViewItem, self.opt, - docsize, self.opt.widget) + QSize(10, 1) + self.style = self.opt.widget.style() + self._get_textdoc(index) + docsize = self.doc.size().toSize() + size = self.style.sizeFromContents(QStyle.CT_ItemViewItem, self.opt, + docsize, self.opt.widget) + return size + QSize(10, 1) def paint(self, painter, option, index): """Override the QStyledItemDelegate paint function.""" @@ -326,22 +328,21 @@ class CompletionItemDelegate(QStyledItemDelegate): self.painter.drawRect(text_rect_.adjusted(0, 0, -1, -1)) self.painter.translate(text_rect.left(), text_rect.top()) - doc = self._get_textdoc(index) - self._draw_textdoc(doc, text_rect) + self._get_textdoc(index) + self._draw_textdoc(text_rect) self.painter.restore() - def _draw_textdoc(self, doc, text_rect): + def _draw_textdoc(self, text_rect): """Draw the QTextDocument of an item. - doc -- The QTextDocument to draw. text_rect -- The QRect to clip the drawing to. """ clip = QRectF(0, 0, text_rect.width(), text_rect.height()) - doc.drawContents(self.painter, clip) + self.doc.drawContents(self.painter, clip) def _get_textdoc(self, index): - """Return the QTextDocument of an item. + """Create the QTextDocument of an item. index -- The QModelIndex of the item to draw. @@ -357,31 +358,30 @@ class CompletionItemDelegate(QStyledItemDelegate): text_option.setAlignment(QStyle.visualAlignment( self.opt.direction, self.opt.displayAlignment)) - doc = QTextDocument() + self.doc = QTextDocument() if index.parent().isValid(): - doc.setPlainText(self.opt.text) + self.doc.setPlainText(self.opt.text) else: - doc.setHtml('{}'.format(html.escape(self.opt.text))) - doc.setDefaultFont(self.opt.font) - doc.setDefaultTextOption(text_option) - doc.setDefaultStyleSheet(config.get_stylesheet(""" + self.doc.setHtml('{}'.format(html.escape(self.opt.text))) + self.doc.setDefaultFont(self.opt.font) + self.doc.setDefaultTextOption(text_option) + self.doc.setDefaultStyleSheet(config.get_stylesheet(""" .highlight {{ {color[completion.match.fg]} }} """)) - doc.setDocumentMargin(2) + self.doc.setDocumentMargin(2) if index.column() == 0: marks = index.data(Qt.UserRole) for mark in marks: - cur = QTextCursor(doc) + cur = QTextCursor(self.doc) cur.setPosition(mark[0]) cur.setPosition(mark[1], QTextCursor.KeepAnchor) txt = cur.selectedText() cur.removeSelectedText() cur.insertHtml('{}'.format( html.escape(txt))) - return doc def _draw_focus_rect(self): """Draw the focus rectangle of an ItemViewItem.""" diff --git a/qutebrowser/widgets/crash.py b/qutebrowser/widgets/crash.py index d12efc9f4..1603be812 100644 --- a/qutebrowser/widgets/crash.py +++ b/qutebrowser/widgets/crash.py @@ -31,14 +31,21 @@ class CrashDialog(QDialog): """Dialog which gets shown after there was a crash.""" + vbox = None + lbl = None + txt = None + hbox = None + btn_quit = None + btn_restore = None + def __init__(self, pages, cmdhist, exc): super().__init__() self.setFixedSize(500, 350) self.setWindowTitle('Whoops!') self.setModal(True) - vbox = QVBoxLayout() - lbl = QLabel(self) + self.vbox = QVBoxLayout() + self.lbl = QLabel(self) text = ('Argh! qutebrowser crashed unexpectedly.
' 'Please review the info below to remove sensitive data and ' 'then submit it to ' @@ -46,29 +53,29 @@ class CrashDialog(QDialog): if pages: text += ('You can click "Restore tabs" to attempt to reopen your ' 'open tabs.') - lbl.setText(text) - lbl.setWordWrap(True) - vbox.addWidget(lbl) + self.lbl.setText(text) + self.lbl.setWordWrap(True) + self.vbox.addWidget(self.lbl) - txt = QTextEdit(self) - txt.setReadOnly(True) - txt.setText(self._crash_info(pages, cmdhist, exc)) - vbox.addWidget(txt) - self.setLayout(vbox) + self.txt = QTextEdit(self) + self.txt.setReadOnly(True) + self.txt.setText(self._crash_info(pages, cmdhist, exc)) + self.vbox.addWidget(self.txt) + self.setLayout(self.vbox) - hbox = QHBoxLayout() - btn_quit = QPushButton(self) - btn_quit.setText('Quit') - btn_quit.clicked.connect(self.reject) - hbox.addWidget(btn_quit) + self.hbox = QHBoxLayout() + self.btn_quit = QPushButton(self) + self.btn_quit.setText('Quit') + self.btn_quit.clicked.connect(self.reject) + self.hbox.addWidget(self.btn_quit) if pages: - btn_restore = QPushButton(self) - btn_restore.setText('Restore tabs') - btn_restore.clicked.connect(self.accept) - btn_restore.setDefault(True) - hbox.addWidget(btn_restore) + self.btn_restore = QPushButton(self) + self.btn_restore.setText('Restore tabs') + self.btn_restore.clicked.connect(self.accept) + self.btn_restore.setDefault(True) + self.hbox.addWidget(self.btn_restore) - vbox.addLayout(hbox) + self.vbox.addLayout(self.hbox) def _crash_info(self, pages, cmdhist, exc): """Gather crash information to display.""" diff --git a/qutebrowser/widgets/statusbar.py b/qutebrowser/widgets/statusbar.py index 52a3158f1..51ad5c8e1 100644 --- a/qutebrowser/widgets/statusbar.py +++ b/qutebrowser/widgets/statusbar.py @@ -34,6 +34,7 @@ class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow.""" + hbox = None cmd = None txt = None keystring = None @@ -43,6 +44,8 @@ class StatusBar(QWidget): resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _error = False + _option = None + _painter = None _stylesheet = """ QWidget#StatusBar[error="false"] {{ {color[statusbar.bg]} @@ -66,28 +69,28 @@ class StatusBar(QWidget): self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) - hbox = QHBoxLayout(self) - hbox.setContentsMargins(0, 0, 0, 0) - hbox.setSpacing(5) + self.hbox = QHBoxLayout(self) + self.hbox.setContentsMargins(0, 0, 0, 0) + self.hbox.setSpacing(5) self.cmd = Command(self) - hbox.addWidget(self.cmd) + self.hbox.addWidget(self.cmd) self.txt = Text(self) - hbox.addWidget(self.txt) - hbox.addStretch() + self.hbox.addWidget(self.txt) + self.hbox.addStretch() self.keystring = KeyString(self) - hbox.addWidget(self.keystring) + self.hbox.addWidget(self.keystring) self.url = Url(self) - hbox.addWidget(self.url) + self.hbox.addWidget(self.url) self.percentage = Percentage(self) - hbox.addWidget(self.percentage) + self.hbox.addWidget(self.percentage) self.prog = Progress(self) - hbox.addWidget(self.prog) + self.hbox.addWidget(self.prog) @pyqtProperty(bool) def error(self): @@ -109,10 +112,11 @@ class StatusBar(QWidget): def paintEvent(self, e): """Override QWIidget.paintEvent to handle stylesheets.""" # pylint: disable=unused-argument - option = QStyleOption() - option.initFrom(self) - painter = QPainter(self) - self.style().drawPrimitive(QStyle.PE_Widget, option, painter, self) + self._option = QStyleOption() + self._option.initFrom(self) + self._painter = QPainter(self) + self.style().drawPrimitive(QStyle.PE_Widget, self._option, + self._painter, self) def disp_error(self, text): """Displaysan error in the statusbar.""" @@ -157,6 +161,7 @@ class Command(QLineEdit): tab_pressed = pyqtSignal(bool) # Emitted when tab is pressed (arg: shift) hide_completion = pyqtSignal() # Hide completion window history = [] # The command history, with newer commands at the bottom + _shortcuts = [] _tmphist = [] _histpos = None @@ -191,6 +196,7 @@ class Command(QLineEdit): sc.setKey(QKeySequence(key)) sc.setContext(Qt.WidgetWithChildrenShortcut) sc.activated.connect(handler) + self._shortcuts.append(sc) def process_cmdline(self): """Handle the command in the status bar.""" @@ -345,6 +351,7 @@ class TextBase(QLabel): elidemode = None _elided_text = None + _painter = None def __init__(self, bar, elidemode=Qt.ElideRight): super().__init__(bar) @@ -375,10 +382,10 @@ class TextBase(QLabel): if self.elidemode == Qt.ElideNone: super().paintEvent(e) else: - painter = QPainter(self) - geom = self.geometry() - painter.drawText(0, 0, geom.width(), geom.height(), - self.alignment(), self._elided_text) + self._painter = QPainter(self) + self._painter.drawText(0, 0, self.geometry().width(), + self.geometry().height(), self.alignment(), + self._elided_text) class Text(TextBase):