diff dwtx/jface/text/projection/FragmentUpdater.d @ 129:eb30df5ca28b

Added JFace Text sources
author Frank Benoit <benoit@tionex.de>
date Sat, 23 Aug 2008 19:10:48 +0200
parents
children c4fb132a086c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/FragmentUpdater.d	Sat Aug 23 19:10:48 2008 +0200
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.FragmentUpdater;
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+
+
+/**
+ * The position updater used to adapt the fragments of a master document. If an
+ * insertion happens at a fragment's offset, the fragment is extended rather
+ * than shifted. Also, the last fragment is extended if an insert operation
+ * happens at the end of the fragment.
+ *
+ * @since 3.0
+ */
+class FragmentUpdater : DefaultPositionUpdater {
+
+    /** Indicates whether the position being updated represents the last fragment. */
+    private bool fIsLast= false;
+
+    /**
+     * Creates the fragment updater for the given category.
+     *
+     * @param fragmentCategory the position category used for managing the fragments of a document
+     */
+    protected FragmentUpdater(String fragmentCategory) {
+        super(fragmentCategory);
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        try {
+
+            Position[] category= event.getDocument().getPositions(getCategory());
+
+            fOffset= event.getOffset();
+            fLength= event.getLength();
+            fReplaceLength= (event.getText() is null ? 0 : event.getText().length());
+            fDocument= event.getDocument();
+
+            for (int i= 0; i < category.length; i++) {
+
+                fPosition= category[i];
+                fIsLast= (i is category.length -1);
+
+                fOriginalPosition.offset= fPosition.offset;
+                fOriginalPosition.length= fPosition.length;
+
+                if (notDeleted())
+                    adaptToReplace();
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // do nothing
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.DefaultPositionUpdater#adaptToInsert()
+     */
+    protected void adaptToInsert() {
+        int myStart= fPosition.offset;
+        int myEnd= Math.max(myStart, fPosition.offset + fPosition.length - (fIsLast || isAffectingReplace() ? 0 : 1));
+
+        if (myEnd < fOffset)
+            return;
+
+        if (fLength <= 0) {
+
+            if (myStart <= fOffset)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+
+        } else {
+
+            if (myStart <= fOffset && fOriginalPosition.offset <= fOffset)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+        }
+    }
+
+    /**
+     * Returns whether this updater considers any position affected by the given document event. A
+     * position is affected if <code>event</code> {@link Position#overlapsWith(int, int) overlaps}
+     * with it but not if the position is only shifted.
+     * 
+     * @param event the event
+     * @return <code>true</code> if there is any affected position, <code>false</code> otherwise
+     */
+    public bool affectsPositions(DocumentEvent event) {
+        IDocument document= event.getDocument();
+        try {
+
+            int index= document.computeIndexInCategory(getCategory(), event.getOffset());
+            Position[] fragments= document.getPositions(getCategory());
+
+            if (0 < index) {
+                Position fragment= fragments[index - 1];
+                if (fragment.overlapsWith(event.getOffset(), event.getLength()))
+                    return true;
+                if (index is fragments.length && fragment.offset + fragment.length is event.getOffset())
+                    return true;
+            }
+
+            if (index < fragments.length) {
+                Position fragment= fragments[index];
+                return fragment.overlapsWith(event.getOffset(), event.getLength());
+            }
+
+        } catch (BadLocationException x) {
+        } catch (BadPositionCategoryException x) {
+        }
+
+        return false;
+    }
+}