diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index fc2f84320d..cc8a4f1c23 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -1,7 +1,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import traceback, os, sys, functools, collections, textwrap +import traceback, os, sys, functools, textwrap from functools import partial from threading import Thread @@ -48,39 +48,57 @@ class Worker(Thread): self.exception = err self.traceback = traceback.format_exc() -class History(collections.deque): +class History(list): def __init__(self, action_back, action_forward): self.action_back = action_back self.action_forward = action_forward - collections.deque.__init__(self) - self.pos = 0 + super(History, self).__init__(self) + self.insert_pos = 0 + self.back_pos = None + self.forward_pos = None self.set_actions() def set_actions(self): - self.action_back.setDisabled(self.pos < 1) - self.action_forward.setDisabled(self.pos + 1 >= len(self)) + self.action_back.setDisabled(self.back_pos is None) + self.action_forward.setDisabled(self.forward_pos is None) def back(self, from_pos): - if self.pos - 1 < 0: return None - if self.pos == len(self): - self.append([]) - self[self.pos] = from_pos - self.pos -= 1 + # Back clicked + if self.back_pos is None: + return None + item = self[self.back_pos] + # The next forward must go to from_pos + self.forward_pos = self.back_pos+1 + if self.forward_pos >= len(self) or self[self.forward_pos] != from_pos: + self.insert(self.forward_pos, from_pos) + self.insert_pos = self.forward_pos + self.back_pos = None if self.back_pos == 0 else self.back_pos - 1 self.set_actions() - return self[self.pos] + return item - def forward(self): - if self.pos + 1 >= len(self): return None - self.pos += 1 + def forward(self, from_pos): + if self.forward_pos is None: + return None + item = self[self.forward_pos] + self.back_pos = self.forward_pos - 1 + if self.back_pos < 0: self.back_pos = None + self.insert_pos = self.back_pos or 0 + self.forward_pos = None if self.forward_pos > len(self) - 2 else self.forward_pos + 1 self.set_actions() - return self[self.pos] + return item def add(self, item): - while len(self) > self.pos+1: - self.pop() - self.append(item) - self.pos += 1 + self[self.insert_pos:] = [] + while self.insert_pos > 0 and self[self.insert_pos-1] == item: + self.insert_pos -= 1 + self[self.insert_pos:] = [] + self.insert(self.insert_pos, item) + # The next back must go to item + self.back_pos = self.insert_pos + self.insert_pos += 1 + # There can be no forward + self.forward_pos = None self.set_actions() class Metadata(QLabel): @@ -665,7 +683,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.goto_page(num) def forward(self, x): - pos = self.history.forward() + pos = self.history.forward(self.pos.value()) if pos is not None: self.goto_page(pos)