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

org.odftoolkit.simple.common.navigation.Selection Maven / Gradle / Ivy

The newest version!
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

package org.odftoolkit.simple.common.navigation;

import java.util.Hashtable;
import java.util.Vector;
import org.odftoolkit.odfdom.pkg.OdfElement;

/**
 * Selection describes one of the matched results, which is
 * recognized by the container element, the start index of the text content in
 * this element and the text content.
 */
public abstract class Selection {

	private OdfElement mElement;
	private int mIndex;
	protected Navigation search;
	public Navigation getNavigation() {
		return search;
	}

	/**
	 * Get the container element of this Selection.
	 *
	 * @return the container element
	 */
	public OdfElement getElement() {
		return mElement;
	}

	/**
	 * Get the start index of the text content in the container element. This is
	 * only meaningful for {@link TextSelection TextSelection} and its sub
	 * classes, other type of Selection will return 0.
	 *
	 * @return the start index of the container element
	 */
	public int getIndex() {
		return mIndex;
	}

	/**
	 * Cut current Selection.
	 *
	 * @throws InvalidNavigationException
	 */
	public abstract void cut() throws InvalidNavigationException;

	/**
	 * Paste current Selection at front of the specified position
	 * Selection.
	 *
	 * @param positionItem
	 *            the position Selection
	 * @throws InvalidNavigationException
	 */
	public abstract void pasteAtFrontOf(Selection positionItem) throws InvalidNavigationException;

	/**
	 * Paste current Selection at end of the specified position
	 * Selection.
	 *
	 * @param positionItem
	 *            the position Selection
	 * @throws InvalidNavigationException
	 */
	public abstract void pasteAtEndOf(Selection positionItem) throws InvalidNavigationException;

	/**
	 * When a selected item has been deleted, the Selections after
	 * this deleted Selection should be refreshed, as these
	 * Selections index have been changed.
	 *
	 * @param deletedItem
	 *            the deleted Selection
	 */
	protected abstract void refreshAfterFrontalDelete(Selection deletedItem);

	/**
	 * When a selected item has been inserted, the Selection after
	 * the inserted item should be refresh, as these Selections
	 * index have been changed.
	 *
	 * @param insertedItem
	 *            the inserted Selection
	 */
	protected abstract void refreshAfterFrontalInsert(Selection insertedItem);

	/**
	 * A quick method to update the index of this Selection.
	 *
	 * @param offset
	 *            the offset that the index should be added.
	 */
	protected abstract void refresh(int offset);

	/**
	 * SelectionManager can manage all the Selections that are
	 * returned to end users. This SelectionManager contains a repository of all
	 * Selections, and will refresh the status/index of
	 * Selections after certain operation.
	 */
	static class SelectionManager {

		private static Hashtable> repository = new Hashtable>();

		/**
		 * Register the Selection item.
		 *
		 * @param item
		 *            the Selection item
		 */
		public static void registerItem(Selection item) {
			OdfElement element = item.getElement();
			if (repository.containsKey(element)) {
				Vector selections = repository.get(element);
				int i = 0;
				while (i < selections.size()) {
					if (selections.get(i).getIndex() > item.getIndex()) {
						selections.insertElementAt(item, i);
						break;
					}
					i++;
				}
				if (i == selections.size()) {
					selections.add(item);
				}
			} else {
				Vector al = new Vector();
				al.add(item);
				repository.put(element, al);
			}
		}

		/**
		 * Refresh the Selections in repository after a item is
		 * cut.
		 *
		 * @param cutItem
		 *            the cut item
		 */
		public synchronized static void refreshAfterCut(Selection cutItem) {
			// travase the whole sub tree
			OdfElement element = cutItem.getElement();
			if (repository.containsKey(element)) {
				Vector selections = repository.get(element);
				for (int i = 0; i < selections.size(); i++) {
					if (selections.get(i).getIndex() > cutItem.getIndex()) {
						selections.get(i).refreshAfterFrontalDelete(cutItem);
					}
				}
			}
		}

		/**
		 * Refresh the selections in repository after pastedAtFrontOf operation
		 * is called.
		 *
		 * @param item
		 *            the pasted item
		 * @param positionItem
		 *            the position item
		 */
		public synchronized static void refreshAfterPasteAtFrontOf(Selection item, Selection positionItem) {
			// travase the whole sub tree
			OdfElement element = positionItem.getElement();
			if (repository.containsKey(element)) {
				Vector selections = repository.get(element);
				for (int i = 0; i < selections.size(); i++) {
					if (selections.get(i).getIndex() >= positionItem.getIndex()) {
						selections.get(i).refreshAfterFrontalInsert(item);
					}
				}
			}
		}

		/**
		 * Refresh the Selections in repository after pastedAtEndOf
		 * operation is called.
		 *
		 * @param item
		 *            the pasted item
		 * @param positionItem
		 *            the position item
		 */
		public synchronized static void refreshAfterPasteAtEndOf(Selection item, Selection positionItem) {
			OdfElement element = positionItem.getElement();
			int positionIndex;
			if (positionItem instanceof TextSelection) {
				positionIndex = positionItem.getIndex() + ((TextSelection) positionItem).getText().length();
			} else {
				positionIndex = positionItem.getIndex();
			}
			if (repository.containsKey(element)) {
				Vector selections = repository.get(element);
				for (int i = 0; i < selections.size(); i++) {
					if (selections.get(i).getIndex() >= positionIndex) {
						selections.get(i).refreshAfterFrontalInsert(item);
					}
				}
			}
		}

		/**
		 * Remove the Selection from repository.
		 *
		 * @param item
		 *            Selection item
		 */
		public static void unregisterItem(Selection item) {
			OdfElement element = item.getElement();
			if (repository.containsKey(element)) {
				Vector selections = repository.get(element);
				selections.remove(item);
			}
		}

		/**
		 * A direct method to update all the Selections contained
		 * in a element after a certain position.
		 *
		 * @param containerElement
		 *            the container element
		 * @param offset
		 *            the offset
		 * @param positionIndex
		 *            the index of a certain position
		 */
		public synchronized static void refresh(OdfElement containerElement, int offset, int positionIndex) {
			if (repository.containsKey(containerElement)) {
				Vector selections = repository.get(containerElement);
				for (int i = 0; i < selections.size(); i++) {
					if (selections.get(i).getIndex() >= positionIndex) {
						selections.get(i).refresh(offset);
					}
				}
			}
		}

		/**
		 * Clears the repository being used by the SelectionManager.
		 * Must be called at the end of Navigation.
		 */
		public static void clearRepository (){
			repository.clear();
		}

		private SelectionManager() {
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy