diff --git a/frontend/apps/reader/modules/readerlink.lua b/frontend/apps/reader/modules/readerlink.lua index 6230abbff..ef3a78d87 100644 --- a/frontend/apps/reader/modules/readerlink.lua +++ b/frontend/apps/reader/modules/readerlink.lua @@ -64,6 +64,7 @@ end local ReaderLink = InputContainer:extend{ location_stack = nil, -- table, per-instance + forward_location_stack = nil, -- table, per-instance _external_link_buttons = nil, } @@ -250,7 +251,7 @@ ReaderLink.onPhysicalKeyboardConnected = ReaderLink.registerKeyEvents function ReaderLink:onReadSettings(config) -- called when loading new document - self.location_stack = {} + self:onClearLocationStack() end local function isTapToFollowLinksOn() @@ -306,6 +307,21 @@ function ReaderLink:addToMainMenu(menu_items) }) end, } + menu_items.go_to_next_location = { + text = _("Go Forward to next location"), + enabled_func = function() return self.forward_location_stack and #self.forward_location_stack > 0 end, + callback = function() self:onGoForwardLink() end, + hold_callback = function(touchmenu_instance) + UIManager:show(ConfirmBox:new{ + text = _("Clear Forward location history?"), + ok_text = _("Clear"), + ok_callback = function() + self:onClearForwardLocationStack() + touchmenu_instance:closeMenu() + end, + }) + end, + } if not Device:isTouchDevice() then -- Menu items below aren't needed. return @@ -662,19 +678,40 @@ function ReaderLink:onTap(_, ges) end end ---- Remember current location so we can go back to it -function ReaderLink:addCurrentLocationToStack() +function ReaderLink:getCurrentLocation() + local location if self.ui.document.info.has_pages then - table.insert(self.location_stack, self.ui.paging:getBookLocation()) + location = self.ui.paging:getBookLocation() else - table.insert(self.location_stack, { - xpointer = self.ui.rolling:getBookLocation(), - }) + location = {xpointer = self.ui.rolling:getBookLocation(),} end + return location +end + +-- Returns true, current_location if the current location is the same as the +-- saved_location on the top of the stack. +-- Otherwise returns false, current_location +function ReaderLink:compareLocationToCurrent(saved_location) + local current_location = self:getCurrentLocation() + if self.ui.rolling and saved_location.xpointer and saved_location.xpointer == current_location.xpointer then + return true, current_location + end + if self.ui.paging and saved_location[1] and current_location[1] and current_location[1].page == saved_location[1].page then + return true, current_location + end + return false, current_location +end + +-- Remember current location so we can go back to it +function ReaderLink:addCurrentLocationToStack(loc) + local location = loc and loc or self:getCurrentLocation() + self:onClearForwardLocationStack() + table.insert(self.location_stack, location) end function ReaderLink:onClearLocationStack(show_notification) self.location_stack = {} + self:onClearForwardLocationStack() if show_notification then UIManager:show(Notification:new{ text = _("Location history cleared."), @@ -683,6 +720,11 @@ function ReaderLink:onClearLocationStack(show_notification) return true end +function ReaderLink:onClearForwardLocationStack() + self.forward_location_stack = {} + return true +end + function ReaderLink:getPreviousLocationPages() local previous_locations = {} if #self.location_stack > 0 then @@ -751,7 +793,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po marker_xpointer = link.from_xpointer, } end - table.insert(self.location_stack, saved_location) + self:addCurrentLocationToStack(saved_location) else self:addCurrentLocationToStack() end @@ -827,6 +869,24 @@ end function ReaderLink:onGoBackLink(show_notification_if_empty) local saved_location = table.remove(self.location_stack) if saved_location then + local same_page, current_location = self:compareLocationToCurrent(saved_location) + -- If there are no forward items + if #self.forward_location_stack == 0 then + -- If we are not on the same page as the current item, + -- then add our current location to the forward stack + if not same_page then + table.insert(self.forward_location_stack, current_location) + end + end + if same_page then + -- If we are on the same page pass through to the next location + table.insert(self.forward_location_stack, saved_location) + saved_location = table.remove(self.location_stack) + end + end + + if saved_location then + table.insert(self.forward_location_stack, saved_location) logger.dbg("GoBack: restoring:", saved_location) self.ui:handleEvent(Event:new('RestoreBookLocation', saved_location)) return true @@ -837,6 +897,26 @@ function ReaderLink:onGoBackLink(show_notification_if_empty) end end +--- Goes to next location. +function ReaderLink:onGoForwardLink() + local saved_location = table.remove(self.forward_location_stack) + if saved_location then + local same_page = self:compareLocationToCurrent(saved_location) + if same_page then + -- If we are on the same page pass through to the next location + table.insert(self.location_stack, saved_location) + saved_location = table.remove(self.forward_location_stack) + end + end + + if saved_location then + table.insert(self.location_stack, saved_location) + logger.dbg("GoForward: restoring:", saved_location) + self.ui:handleEvent(Event:new('RestoreBookLocation', saved_location)) + return true + end +end + function ReaderLink:onSwipe(arg, ges) local direction = BD.flipDirectionIfMirroredUILayout(ges.direction) if direction == "east" then diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index 9449ff3e2..f58b3268d 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -123,6 +123,7 @@ local settingsList = { skim = {category="none", event="ShowSkimtoDialog", title=_("Skim document"), reader=true}, back = {category="none", event="Back", title=_("Back"), reader=true}, previous_location = {category="none", event="GoBackLink", arg=true, title=_("Back to previous location"), reader=true}, + next_location = {category="none", event="GoForwardLink", arg=true, title=_("Forward to next location"), reader=true}, latest_bookmark = {category="none", event="GoToLatestBookmark", title=_("Go to latest bookmark"), reader=true}, follow_nearest_link = {category="arg", event="GoToPageLink", arg={pos={x=0,y=0}}, title=_("Follow nearest link"), reader=true}, follow_nearest_internal_link = {category="arg", event="GoToInternalPageLink", arg={pos={x=0,y=0}}, title=_("Follow nearest internal link"), reader=true}, @@ -307,6 +308,7 @@ local dispatcher_menu_order = { "latest_bookmark", "back", "previous_location", + "next_location", "follow_nearest_link", "follow_nearest_internal_link", "clear_location_history", diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index b124d99d1..df057ee67 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -28,6 +28,7 @@ local order = { "autoturn", "----------------------------", "go_to_previous_location", + "go_to_next_location", }, navi_settings = { "toc_alt_toc",