693 marks = new MarkVector();
694 search = new MarkData(0);
695 queue = new ReferenceQueue<StickyPosition>();
696 }
697
698
699 // --- undo support --------------------------------------
700
701 /**
702 * Returns a Vector containing instances of UndoPosRef for the
703 * Positions in the range
704 * <code>offset</code> to <code>offset</code> + <code>length</code>.
705 * If <code>v</code> is not null the matching Positions are placed in
706 * there. The vector with the resulting Positions are returned.
707 *
708 * @param v the Vector to use, with a new one created on null
709 * @param offset the starting offset >= 0
710 * @param length the length >= 0
711 * @return the set of instances
712 */
713 protected Vector<UndoPosRef> getPositionsInRange(Vector<UndoPosRef> v,
714 int offset, int length) {
715 int endOffset = offset + length;
716 int startIndex;
717 int endIndex;
718 int g0 = getGapStart();
719 int g1 = getGapEnd();
720
721 // Find the index of the marks.
722 if (offset < g0) {
723 if (offset == 0) {
724 // findMarkAdjustIndex start at 1!
725 startIndex = 0;
726 }
727 else {
728 startIndex = findMarkAdjustIndex(offset);
729 }
730 if (endOffset >= g0) {
731 endIndex = findMarkAdjustIndex(endOffset + (g1 - g0) + 1);
732 }
733 else {
741
742 Vector<UndoPosRef> placeIn = (v == null) ?
743 new Vector<>(Math.max(1, endIndex - startIndex)) :
744 v;
745
746 for (int counter = startIndex; counter < endIndex; counter++) {
747 placeIn.addElement(new UndoPosRef(marks.elementAt(counter)));
748 }
749 return placeIn;
750 }
751
752 /**
753 * Resets the location for all the UndoPosRef instances
754 * in <code>positions</code>.
755 * <p>
756 * This is meant for internal usage, and is generally not of interest
757 * to subclasses.
758 *
759 * @param positions the UndoPosRef instances to reset
760 */
761 protected void updateUndoPositions(Vector<UndoPosRef> positions, int offset,
762 int length) {
763 // Find the indexs of the end points.
764 int endOffset = offset + length;
765 int g1 = getGapEnd();
766 int startIndex;
767 int endIndex = findMarkAdjustIndex(g1 + 1);
768
769 if (offset != 0) {
770 startIndex = findMarkAdjustIndex(g1);
771 }
772 else {
773 startIndex = 0;
774 }
775
776 // Reset the location of the refenences.
777 for(int counter = positions.size() - 1; counter >= 0; counter--) {
778 UndoPosRef ref = positions.elementAt(counter);
779 ref.resetLocation(endOffset, g1);
780 }
781 // We have to resort the marks in the range startIndex to endIndex.
782 // We can take advantage of the fact that it will be in
783 // increasing order, accept there will be a bunch of MarkData's with
784 // the index g1 (or 0 if offset == 0) interspersed throughout.
785 if (startIndex < endIndex) {
786 Object[] sorted = new Object[endIndex - startIndex];
787 int addIndex = 0;
788 int counter;
789 if (offset == 0) {
790 // If the offset is 0, the positions won't have incremented,
791 // have to do the reverse thing.
792 // Find the elements in startIndex whose index is 0
793 for (counter = startIndex; counter < endIndex; counter++) {
794 MarkData mark = marks.elementAt(counter);
795 if (mark.index == 0) {
796 sorted[addIndex++] = mark;
797 }
798 }
885 string = null;
886 // Update the Positions that were in the range removed.
887 if(posRefs != null) {
888 updateUndoPositions(posRefs, offset, length);
889 posRefs = null;
890 }
891 } catch (BadLocationException bl) {
892 throw new CannotRedoException();
893 }
894 }
895
896 /** Where string was inserted. */
897 protected int offset;
898 /** Length of string inserted. */
899 protected int length;
900 /** The string that was inserted. This will only be valid after an
901 * undo. */
902 protected String string;
903 /** An array of instances of UndoPosRef for the Positions in the
904 * range that was removed, valid after undo. */
905 protected Vector<UndoPosRef> posRefs;
906 } // GapContent.InsertUndo
907
908
909 /**
910 * UndoableEdit created for removes.
911 */
912 @SuppressWarnings("serial") // JDK-implementation class
913 class RemoveUndo extends AbstractUndoableEdit {
914 protected RemoveUndo(int offset, String string) {
915 super();
916 this.offset = offset;
917 this.string = string;
918 this.length = string.length();
919 posRefs = getPositionsInRange(null, offset, length);
920 }
921
922 public void undo() throws CannotUndoException {
923 super.undo();
924 try {
925 insertString(offset, string);
926 // Update the Positions that were in the range removed.
927 if(posRefs != null) {
928 updateUndoPositions(posRefs, offset, length);
929 posRefs = null;
930 }
931 string = null;
932 } catch (BadLocationException bl) {
933 throw new CannotUndoException();
934 }
935 }
936
937 public void redo() throws CannotRedoException {
938 super.redo();
939 try {
940 string = getString(offset, length);
941 // Get the Positions in the range being removed.
942 posRefs = getPositionsInRange(null, offset, length);
943 remove(offset, length);
944 } catch (BadLocationException bl) {
945 throw new CannotRedoException();
946 }
947 }
948
949 /** Where the string was removed from. */
950 protected int offset;
951 /** Length of string removed. */
952 protected int length;
953 /** The string that was removed. This is valid when redo is valid. */
954 protected String string;
955 /** An array of instances of UndoPosRef for the Positions in the
956 * range that was removed, valid before undo. */
|
693 marks = new MarkVector();
694 search = new MarkData(0);
695 queue = new ReferenceQueue<StickyPosition>();
696 }
697
698
699 // --- undo support --------------------------------------
700
701 /**
702 * Returns a Vector containing instances of UndoPosRef for the
703 * Positions in the range
704 * <code>offset</code> to <code>offset</code> + <code>length</code>.
705 * If <code>v</code> is not null the matching Positions are placed in
706 * there. The vector with the resulting Positions are returned.
707 *
708 * @param v the Vector to use, with a new one created on null
709 * @param offset the starting offset >= 0
710 * @param length the length >= 0
711 * @return the set of instances
712 */
713 @SuppressWarnings({"rawtypes", "unchecked"}) // UndoPosRef type cannot be exposed
714 protected Vector getPositionsInRange(Vector v,
715 int offset, int length) {
716 int endOffset = offset + length;
717 int startIndex;
718 int endIndex;
719 int g0 = getGapStart();
720 int g1 = getGapEnd();
721
722 // Find the index of the marks.
723 if (offset < g0) {
724 if (offset == 0) {
725 // findMarkAdjustIndex start at 1!
726 startIndex = 0;
727 }
728 else {
729 startIndex = findMarkAdjustIndex(offset);
730 }
731 if (endOffset >= g0) {
732 endIndex = findMarkAdjustIndex(endOffset + (g1 - g0) + 1);
733 }
734 else {
742
743 Vector<UndoPosRef> placeIn = (v == null) ?
744 new Vector<>(Math.max(1, endIndex - startIndex)) :
745 v;
746
747 for (int counter = startIndex; counter < endIndex; counter++) {
748 placeIn.addElement(new UndoPosRef(marks.elementAt(counter)));
749 }
750 return placeIn;
751 }
752
753 /**
754 * Resets the location for all the UndoPosRef instances
755 * in <code>positions</code>.
756 * <p>
757 * This is meant for internal usage, and is generally not of interest
758 * to subclasses.
759 *
760 * @param positions the UndoPosRef instances to reset
761 */
762 @SuppressWarnings("rawtypes") // UndoPosRef type cannot be exposed
763 protected void updateUndoPositions(Vector positions, int offset,
764 int length) {
765 // Find the indexs of the end points.
766 int endOffset = offset + length;
767 int g1 = getGapEnd();
768 int startIndex;
769 int endIndex = findMarkAdjustIndex(g1 + 1);
770
771 if (offset != 0) {
772 startIndex = findMarkAdjustIndex(g1);
773 }
774 else {
775 startIndex = 0;
776 }
777
778 // Reset the location of the refenences.
779 for(int counter = positions.size() - 1; counter >= 0; counter--) {
780 UndoPosRef ref = (UndoPosRef)positions.elementAt(counter);
781 ref.resetLocation(endOffset, g1);
782 }
783 // We have to resort the marks in the range startIndex to endIndex.
784 // We can take advantage of the fact that it will be in
785 // increasing order, accept there will be a bunch of MarkData's with
786 // the index g1 (or 0 if offset == 0) interspersed throughout.
787 if (startIndex < endIndex) {
788 Object[] sorted = new Object[endIndex - startIndex];
789 int addIndex = 0;
790 int counter;
791 if (offset == 0) {
792 // If the offset is 0, the positions won't have incremented,
793 // have to do the reverse thing.
794 // Find the elements in startIndex whose index is 0
795 for (counter = startIndex; counter < endIndex; counter++) {
796 MarkData mark = marks.elementAt(counter);
797 if (mark.index == 0) {
798 sorted[addIndex++] = mark;
799 }
800 }
887 string = null;
888 // Update the Positions that were in the range removed.
889 if(posRefs != null) {
890 updateUndoPositions(posRefs, offset, length);
891 posRefs = null;
892 }
893 } catch (BadLocationException bl) {
894 throw new CannotRedoException();
895 }
896 }
897
898 /** Where string was inserted. */
899 protected int offset;
900 /** Length of string inserted. */
901 protected int length;
902 /** The string that was inserted. This will only be valid after an
903 * undo. */
904 protected String string;
905 /** An array of instances of UndoPosRef for the Positions in the
906 * range that was removed, valid after undo. */
907 @SuppressWarnings("rawtypes") // UndoPosRef type cannot be exposed
908 protected Vector posRefs;
909 } // GapContent.InsertUndo
910
911
912 /**
913 * UndoableEdit created for removes.
914 */
915 @SuppressWarnings("serial") // JDK-implementation class
916 class RemoveUndo extends AbstractUndoableEdit {
917 @SuppressWarnings("unchecked")
918 protected RemoveUndo(int offset, String string) {
919 super();
920 this.offset = offset;
921 this.string = string;
922 this.length = string.length();
923 posRefs = getPositionsInRange(null, offset, length);
924 }
925
926 public void undo() throws CannotUndoException {
927 super.undo();
928 try {
929 insertString(offset, string);
930 // Update the Positions that were in the range removed.
931 if(posRefs != null) {
932 updateUndoPositions(posRefs, offset, length);
933 posRefs = null;
934 }
935 string = null;
936 } catch (BadLocationException bl) {
937 throw new CannotUndoException();
938 }
939 }
940
941 @SuppressWarnings("unchecked")
942 public void redo() throws CannotRedoException {
943 super.redo();
944 try {
945 string = getString(offset, length);
946 // Get the Positions in the range being removed.
947 posRefs = getPositionsInRange(null, offset, length);
948 remove(offset, length);
949 } catch (BadLocationException bl) {
950 throw new CannotRedoException();
951 }
952 }
953
954 /** Where the string was removed from. */
955 protected int offset;
956 /** Length of string removed. */
957 protected int length;
958 /** The string that was removed. This is valid when redo is valid. */
959 protected String string;
960 /** An array of instances of UndoPosRef for the Positions in the
961 * range that was removed, valid before undo. */
|