Prevent duplicates in history completion.

Two things here. One is to use `WebHistory._new_history` only as a to-save
queue, so we now add entries to `_old_urls` when they are first created and
can now no longer iterate of `_new_history` in `__iter__()`.

Second is to stop blindly tacking new history entries on the end of the
history completion model. It does involve iterating over the model to find the
existing entry but we only do that if we know the duplicate is there, which is
fast to check.

This also ads another point of mutation to the history completion model which
may prove problematic if it leads to more segfaults.
This commit is contained in:
Jimmy 2015-03-12 20:15:03 +13:00
parent 734268187c
commit 1efe18ecc6
2 changed files with 19 additions and 8 deletions

View File

@ -99,8 +99,7 @@ class WebHistory(QWebHistoryInterface):
return self._new_history[key]
def __iter__(self):
return itertools.chain(self._old_urls.values(),
iter(self._new_history))
return self._old_urls.values().__iter__()
def get_recent(self):
"""Get the most recent history entries."""
@ -123,6 +122,7 @@ class WebHistory(QWebHistoryInterface):
if not config.get('general', 'private-browsing'):
entry = HistoryEntry(time.time(), url_string)
self._new_history.append(entry)
self._old_urls[url_string] = entry
self.item_added.emit(entry)
def historyContains(self, url_string):

View File

@ -19,7 +19,8 @@
"""CompletionModels for URLs."""
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtGui import QStandardItem
from qutebrowser.utils import objreg
from qutebrowser.completion.models import base
@ -40,22 +41,32 @@ class UrlCompletionModel(base.BaseCompletionModel):
self._history_cat = self.new_category("History")
quickmarks = objreg.get('quickmark-manager').marks.items()
history = objreg.get('web-history')
self._history = objreg.get('web-history')
for qm_name, qm_url in quickmarks:
self.new_item(self._quickmark_cat, qm_url, qm_name)
for entry in history:
for entry in self._history:
atime = int(entry.atime)
self.new_item(self._history_cat, entry.url, "", str(atime),
sort=atime)
history.item_added.connect(self.on_history_item_added)
self._history.item_added.connect(self.on_history_item_added)
@pyqtSlot(object)
def on_history_item_added(self, item):
"""Slot called when a new history item was added."""
if item.url:
atime = int(item.atime)
self.new_item(self._quickmark_cat, item.url, "", str(atime),
if self._history.historyContains(item.url):
for i in range(self._history_cat.rowCount()):
name = self._history_cat.child(i, 0)
if not name:
continue
if name.text() == item.url:
self._history_cat.setChild(i, 2, QStandardItem(str(atime)))
name.setData(str(atime), base.Role.sort)
break
else:
self.new_item(self._history_cat, item.url, "", str(atime),
sort=atime)