All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.siegmann.epublib.browsersupport.NavigationHistory Maven / Gradle / Ivy

package nl.siegmann.epublib.browsersupport;

import java.util.ArrayList;
import java.util.List;

import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Resource;



/**
 * A history of the user's locations with the epub.
 * 
 * @author paul.siegmann
 *
 */
public class NavigationHistory implements NavigationEventListener {

	public static final int DEFAULT_MAX_HISTORY_SIZE = 1000;
	private static final long DEFAULT_HISTORY_WAIT_TIME = 1000;
	
	private static class Location {
		private String href;

		public Location(String href) {
			super();
			this.href = href;
		}

		@SuppressWarnings("unused")
		public void setHref(String href) {
			this.href = href;
		}

		public String getHref() {
			return href;
		}
	}
	
	private long lastUpdateTime = 0;
	private List locations = new ArrayList();
	private Navigator navigator;
	private int currentPos = -1;
	private int currentSize = 0;
	private int maxHistorySize = DEFAULT_MAX_HISTORY_SIZE;
	private long historyWaitTime = DEFAULT_HISTORY_WAIT_TIME;

	public NavigationHistory(Navigator navigator) {
		this.navigator = navigator;
		navigator.addNavigationEventListener(this);
		initBook(navigator.getBook());
	}
	
	public int getCurrentPos() {
		return currentPos;
	}


	public int getCurrentSize() {
		return currentSize;
	}
	
	public void initBook(Book book) {
		if (book == null) {
			return;
		}
		locations = new ArrayList();
		currentPos = -1;
		currentSize = 0;
		if (navigator.getCurrentResource() != null) {
			addLocation(navigator.getCurrentResource().getHref());
		}
	}
	
	/**
	 * If the time between a navigation event is less than the historyWaitTime then the new location is not added to the history. 
	 * When a user is rapidly viewing many pages using the slider we do not want all of them to be added to the history.
	 * 
	 * @return the time we wait before adding the page to the history
	 */
	public long getHistoryWaitTime() {
		return historyWaitTime;
	}

	public void setHistoryWaitTime(long historyWaitTime) {
		this.historyWaitTime = historyWaitTime;
	}

	public void addLocation(Resource resource) {
		if (resource == null) {
			return;
		}
		addLocation(resource.getHref());
	}
	
	/**
	 * Adds the location after the current position.
	 * If the currentposition is not the end of the list then the elements between the current element and the end of the list will be discarded.
	 * Does nothing if the new location matches the current location.
	 * 
* If this nr of locations becomes larger then the historySize then the first item(s) will be removed. * * @param location */ public void addLocation(Location location) { // do nothing if the new location matches the current location if ( !(locations.isEmpty()) && location.getHref().equals(locations.get(currentPos).getHref())) { return; } currentPos++; if (currentPos != currentSize) { locations.set(currentPos, location); } else { locations.add(location); checkHistorySize(); } currentSize = currentPos + 1; } /** * Removes all elements that are too much for the maxHistorySize out of the history. * */ private void checkHistorySize() { while(locations.size() > maxHistorySize) { locations.remove(0); currentSize--; currentPos--; } } public void addLocation(String href) { addLocation(new Location(href)); } private String getLocationHref(int pos) { if (pos < 0 || pos >= locations.size()) { return null; } return locations.get(currentPos).getHref(); } /** * Moves the current positions delta positions. * * move(-1) to go one position back in history.
* move(1) to go one position forward.
* * @param delta * * @return Whether we actually moved. If the requested value is illegal it will return false, true otherwise. */ public boolean move(int delta) { if (((currentPos + delta) < 0) || ((currentPos + delta) >= currentSize)) { return false; } currentPos += delta; navigator.gotoResource(getLocationHref(currentPos), this); return true; } /** * If this is not the source of the navigationEvent then the addLocation will be called with the href of the currentResource in the navigationEvent. */ @Override public void navigationPerformed(NavigationEvent navigationEvent) { if (this == navigationEvent.getSource()) { return; } if (navigationEvent.getCurrentResource() == null) { return; } if ((System.currentTimeMillis() - this.lastUpdateTime) > historyWaitTime) { // if the user scrolled rapidly through the pages then the last page will not be added to the history. We fix that here: addLocation(navigationEvent.getOldResource()); addLocation(navigationEvent.getCurrentResource().getHref()); } lastUpdateTime = System.currentTimeMillis(); } public String getCurrentHref() { if (currentPos < 0 || currentPos >= locations.size()) { return null; } return locations.get(currentPos).getHref(); } public void setMaxHistorySize(int maxHistorySize) { this.maxHistorySize = maxHistorySize; } public int getMaxHistorySize() { return maxHistorySize; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy