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.
This commit is contained in:
Jimmy 2016-04-22 22:43:25 +12:00
parent 77a9bbb4b4
commit 32edd35c7a

View File

@ -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)