| /************************************************************************ |
| * |
| * 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.odfdom.incubator.search; |
| |
| import java.util.Hashtable; |
| import java.util.Vector; |
| |
| import org.odftoolkit.odfdom.pkg.OdfElement; |
| |
| /** |
| * Abstract class Selection describe one of the matched results The selection |
| * can be recognized by the container mElement, the start mIndex of the text |
| * content of this mElement and the text content. |
| * |
| * @deprecated As of release 0.8.8, replaced by {@link org.odftoolkit.simple.common.navigation.Selection} in Simple API. |
| */ |
| public abstract class Selection { |
| |
| private OdfElement mElement; |
| private int mIndex; |
| |
| /** |
| * get the container mElement of this selection |
| * @return the container mElement |
| */ |
| public OdfElement getElement() { |
| return mElement; |
| } |
| |
| /** |
| * get the start mIndex of the text content of the container mElement |
| * this is only meaningful for TextSelection. other type Selection |
| * will return 0. |
| * @return the start mIndex of the container mElement |
| */ |
| public int getIndex() { |
| return mIndex; |
| } |
| |
| /** |
| * cut the current selection |
| * @throws InvalidNavigationException |
| */ |
| abstract public void cut() throws InvalidNavigationException; |
| |
| /** |
| * paste the current selection at front of the specified position selection |
| * @param positionitem the position selection |
| * @throws InvalidNavigationException |
| */ |
| abstract public void pasteAtFrontOf(Selection positionitem) throws InvalidNavigationException; |
| |
| /** |
| * paste the current selection at end of the specified position selection |
| * @param positionitem the position selection |
| * @throws InvalidNavigationException |
| */ |
| abstract public void pasteAtEndOf(Selection positionitem) throws InvalidNavigationException; |
| |
| /** |
| * when a selected item has been delete, the selections after this deleted selection should be refresh |
| * because these selections mIndex will be changed |
| * @param deleteditem the deleted selection |
| */ |
| abstract protected void refreshAfterFrontalDelete(Selection deleteditem); |
| |
| /** |
| * when a selected item has been inserted, the selection after the inserted item should be refresh |
| * because these selections mIndex will be changed |
| * @param inserteditem the inserted selection |
| */ |
| abstract protected void refreshAfterFrontalInsert(Selection inserteditem); |
| |
| /** |
| * A quick method to update the mIndex of this selection |
| * @param offset the offset that the mIndex should be added |
| */ |
| abstract protected 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/mIndex |
| * of selections after certain operation. |
| */ |
| static class SelectionManager { |
| |
| static private Hashtable<OdfElement, Vector<Selection>> repository = new Hashtable<OdfElement, Vector<Selection>>(); |
| |
| /** |
| * Register the selection item |
| * @param item the selection item |
| */ |
| static public void registerItem(Selection item) { |
| OdfElement element = item.getElement(); |
| if (repository.containsKey(element)) { |
| Vector<Selection> 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<Selection> al = new Vector<Selection>(); |
| al.add(item); |
| repository.put(element, al); |
| } |
| } |
| |
| /** |
| * Refresh the selections in repository after a item is cut. |
| * @param cutItem the cut item |
| */ |
| synchronized static public void refreshAfterCut(Selection cutItem) { |
| //travase the whole sub tree |
| OdfElement element = cutItem.getElement(); |
| if (repository.containsKey(element)) { |
| Vector<Selection> 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 a pastedAtFrontOf operation is called. |
| * @param item the pasted item |
| * @param positionItem the position item |
| */ |
| synchronized static public void refreshAfterPasteAtFrontOf(Selection item, Selection positionItem) { |
| //travase the whole sub tree |
| OdfElement element = positionItem.getElement(); |
| if (repository.containsKey(element)) { |
| Vector<Selection> 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 a pastedAtEndOf operation is called. |
| * @param item the pasted item |
| * @param positionItem the position item |
| */ |
| synchronized static public 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<Selection> 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 |
| */ |
| static public void unregisterItem(Selection item) { |
| OdfElement element = item.getElement(); |
| if (repository.containsKey(element)) { |
| Vector<Selection> selections = repository.get(element); |
| selections.remove(item); |
| } |
| } |
| |
| /** |
| * A direct method to update all the selections contained in a mElement after a certain position. |
| * @param containerElement the container mElement |
| * @param offset the offset |
| * @param positionIndex the mIndex of a certain position |
| */ |
| synchronized static public void refresh(OdfElement containerElement, int offset, int positionIndex) { |
| if (repository.containsKey(containerElement)) { |
| Vector<Selection> selections = repository.get(containerElement); |
| for (int i = 0; i < selections.size(); i++) { |
| if (selections.get(i).getIndex() >= positionIndex) { |
| selections.get(i).refresh(offset); |
| } |
| } |
| } |
| } |
| |
| private SelectionManager() { |
| } |
| } |
| } |