From 32edd35c7a1a16bb8ba65bcd1ff63857dbf8f862 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 22 Apr 2016 22:43:25 +1200 Subject: [PATCH] buffer completion: handle deleting items see issue #1443 Allows to use ctrl+d to close tabs from the buffer completion widget when they are selected. Respects current tab settings like whether you can close the last tab in a window. Had to change the `rebuild()` method to use `setData()` when possible because the selection was being lost if the whole model was being rebuilt. Current problems are: 1) When opening a new window while you already the tab completion open on one window a category is added for the new window but new rows in that category aren't picked up. Interesting if you open a third window then close the second window the completion display is now correct... I can see that the model is being updated correctly but I am not sure why that isn't propagating to the view. Not sure whether it is worth looking into (further) either. 2) Bit of duplication of code, it iterates over the window registry twice. Could put everything in one loop but then that would be dependant on the current behaviour of the `tab_closed` signal being called with the relevant `tabbed_browser` still existing but with the `shutting_down` flag set. 3) I'm still using just the one `rebuild()` method and removing items from the end then calling `setData` on everything rather than having special `on_tab/window_closed` methods (or partial functions) that delete the actual corresponding item. Because if I did that I would also have to special case tab moves etc. --- qutebrowser/completion/models/miscmodels.py | 61 ++++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/qutebrowser/completion/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py index 3b71a6548..a13604b58 100644 --- a/qutebrowser/completion/models/miscmodels.py +++ b/qutebrowser/completion/models/miscmodels.py @@ -23,7 +23,7 @@ from PyQt5.QtCore import Qt, QTimer, pyqtSlot from qutebrowser.browser import webview from qutebrowser.config import config, configdata -from qutebrowser.utils import objreg, log +from qutebrowser.utils import objreg, log, qtutils from qutebrowser.commands import cmdutils from qutebrowser.completion.models import base @@ -153,7 +153,7 @@ class TabCompletionModel(base.BaseCompletionModel): # https://github.com/The-Compiler/qutebrowser/issues/545 # pylint: disable=abstract-method - #IDX_COLUMN = 0 + IDX_COLUMN = 0 URL_COLUMN = 1 TEXT_COLUMN = 2 @@ -204,15 +204,58 @@ class TabCompletionModel(base.BaseCompletionModel): make sure we handled background loads too ... but iterating over a few/few dozen/few hundred tabs doesn't take very long at all. """ - self.removeRows(0, self.rowCount()) + window_count = 0 for win_id in objreg.window_registry: + tabbed_browser = objreg.get('tabbed-browser', scope='window', + window=win_id) + if not tabbed_browser.shutting_down: + window_count = window_count + 1 + + if window_count < self.rowCount(): + self.removeRows(window_count, self.rowCount()-window_count) + + for i, win_id in enumerate(objreg.window_registry): tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id) if tabbed_browser.shutting_down: continue - c = self.new_category("{}".format(win_id)) - for i in range(tabbed_browser.count()): - tab = tabbed_browser.widget(i) - self.new_item(c, "{}/{}".format(win_id, i+1), - tab.url().toDisplayString(), - tabbed_browser.page_title(i)) + if i >= self.rowCount(): + c = self.new_category("{}".format(win_id)) + else: + c = self.item(i, 0) + c.setData("{}".format(win_id), Qt.DisplayRole) + if tabbed_browser.count() < c.rowCount(): + c.removeRows(tabbed_browser.count(), + c.rowCount()-tabbed_browser.count()) + for idx in range(tabbed_browser.count()): + tab = tabbed_browser.widget(idx) + if idx >= c.rowCount(): + self.new_item(c, "{}/{}".format(win_id, idx+1), + tab.url().toDisplayString(), + tabbed_browser.page_title(idx)) + else: + c.child(idx, 0).setData("{}/{}".format(win_id, idx+1), + Qt.DisplayRole) + c.child(idx, 1).setData(tab.url().toDisplayString(), + Qt.DisplayRole) + c.child(idx, 2).setData(tabbed_browser.page_title(idx), + Qt.DisplayRole) + + def delete_cur_item(self, completion): + """Delete the selected item. + + Args: + completion: The Completion object to use. + """ + index = completion.currentIndex() + qtutils.ensure_valid(index) + category = index.parent() + qtutils.ensure_valid(category) + index = category.child(index.row(), self.IDX_COLUMN) + win_id, tab_index = index.data().split('/') + win_id = int(win_id) + tab_index = int(tab_index) + + tabbed_browser = objreg.get('tabbed-browser', scope='window', + window=win_id) + tabbed_browser.on_tab_close_requested(tab_index-1)