From 1efe18ecc630e06e1eda7b126a8bc9dc7374f969 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 12 Mar 2015 20:15:03 +1300 Subject: [PATCH] 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. --- qutebrowser/browser/history.py | 4 ++-- qutebrowser/completion/models/urlmodel.py | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py index 18042c18e..309fd317b 100644 --- a/qutebrowser/browser/history.py +++ b/qutebrowser/browser/history.py @@ -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): diff --git a/qutebrowser/completion/models/urlmodel.py b/qutebrowser/completion/models/urlmodel.py index 5cf8b708e..485c91184 100644 --- a/qutebrowser/completion/models/urlmodel.py +++ b/qutebrowser/completion/models/urlmodel.py @@ -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), - sort=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)