jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java
author malenkov
Tue, 29 Oct 2013 17:01:06 +0400
changeset 21278 ef8a3a2a72f2
parent 20458 f2423fb3fd19
child 22574 7f8ce0c8c20a
permissions -rw-r--r--
8022746: List of spelling errors in API doc Reviewed-by: alexsch, smarks
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 7014
diff changeset
     2
 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
package javax.swing.text;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
import java.awt.Color;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.font.TextAttribute;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.lang.ref.ReferenceQueue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.lang.ref.WeakReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.Stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.Vector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.io.ObjectInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import javax.swing.event.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import javax.swing.undo.AbstractUndoableEdit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import javax.swing.undo.CannotRedoException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import javax.swing.undo.CannotUndoException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import javax.swing.undo.UndoableEdit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import javax.swing.SwingUtilities;
5763
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
    48
import static sun.swing.SwingUtilities2.IMPLIED_CR;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * A document that can be marked up with character and paragraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * styles in a manner similar to the Rich Text Format.  The element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * structure for this document represents style crossings for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * style runs.  These style runs are mapped into a paragraph element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * structure (which may reside in some other structure).  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * style runs break at paragraph boundaries since logical styles are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * assigned to paragraph boundaries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * <strong>Warning:</strong>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * Serialized objects of this class will not be compatible with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * future Swing releases. The current serialization support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * appropriate for short term storage or RMI between applications running
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * the same version of Swing.  As of 1.4, support for long term storage
20458
f2423fb3fd19 8025840: Fix all the doclint warnings about trademark
cl
parents: 20455
diff changeset
    64
 * of all JavaBeans&trade;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * has been added to the <code>java.beans</code> package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * Please see {@link java.beans.XMLEncoder}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * @author  Timothy Prinzing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * @see     Document
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * @see     AbstractDocument
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
public class DefaultStyledDocument extends AbstractDocument implements StyledDocument {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     * Constructs a styled document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     * @param c  the container for the content
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * @param styles resources and style definitions which may
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     *  be shared across documents
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    public DefaultStyledDocument(Content c, StyleContext styles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        super(c, styles);
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
    83
        listeningStyles = new Vector<Style>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        buffer = new ElementBuffer(createDefaultRoot());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        Style defaultStyle = styles.getStyle(StyleContext.DEFAULT_STYLE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        setLogicalStyle(0, defaultStyle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * Constructs a styled document with the default content
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * storage implementation and a shared set of styles.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * @param styles the styles
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    public DefaultStyledDocument(StyleContext styles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        this(new GapContent(BUFFER_SIZE_DEFAULT), styles);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * Constructs a default styled document.  This buffers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * input content by a size of <em>BUFFER_SIZE_DEFAULT</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * and has a style context that is scoped by the lifetime
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * of the document and is not shared with other documents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    public DefaultStyledDocument() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleContext());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * Gets the default root element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * @return the root
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * @see Document#getDefaultRootElement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    public Element getDefaultRootElement() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        return buffer.getRootElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * Initialize the document to reflect the given element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * structure (i.e. the structure reported by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * <code>getDefaultRootElement</code> method.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * document contained any data it will first be removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    protected void create(ElementSpec[] data) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            if (getLength() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                remove(0, getLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            // install the content
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            Content c = getContent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            int n = data.length;
7014
eb4fcf73ee99 6432566: Replace usage of StringBuffer with StringBuilder in Swing
rupashka
parents: 5763
diff changeset
   135
            StringBuilder sb = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            for (int i = 0; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                ElementSpec es = data[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                if (es.getLength() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                    sb.append(es.getArray(), es.getOffset(),  es.getLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            UndoableEdit cEdit = c.insertString(0, sb.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            // build the event and element structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            int length = sb.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            DefaultDocumentEvent evnt =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                new DefaultDocumentEvent(0, length, DocumentEvent.EventType.INSERT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            evnt.addEdit(cEdit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            buffer.create(length, data, evnt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            // update bidi (possibly)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            super.insertUpdate(evnt, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            // notify the listeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            evnt.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            fireInsertUpdate(evnt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            fireUndoableEditUpdate(new UndoableEditEvent(this, evnt));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        } catch (BadLocationException ble) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            throw new StateInvariantError("problem initializing");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * Inserts new elements in bulk.  This is useful to allow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * parsing with the document in an unlocked state and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * prepare an element structure modification.  This method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * takes an array of tokens that describe how to update an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * element structure so the time within a write lock can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * be greatly reduced in an asynchronous update situation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * This method is thread safe, although most Swing methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * are not. Please see
20455
f6f9a0c2796b 8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents: 20158
diff changeset
   176
     * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
10316
8d1ca7d93fb2 7075563: Broken link in "javax.swing.SwingWorker"
rupashka
parents: 7668
diff changeset
   177
     * in Swing</A> for more information.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   179
     * @param offset the starting offset &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     * @param data the element data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * @exception BadLocationException for an invalid starting offset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    protected void insert(int offset, ElementSpec[] data) throws BadLocationException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        if (data == null || data.length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            // install the content
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            Content c = getContent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            int n = data.length;
7014
eb4fcf73ee99 6432566: Replace usage of StringBuffer with StringBuilder in Swing
rupashka
parents: 5763
diff changeset
   194
            StringBuilder sb = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            for (int i = 0; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                ElementSpec es = data[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                if (es.getLength() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                    sb.append(es.getArray(), es.getOffset(),  es.getLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            if (sb.length() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                // Nothing to insert, bail.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            UndoableEdit cEdit = c.insertString(offset, sb.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            // create event and build the element structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            int length = sb.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            DefaultDocumentEvent evnt =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                new DefaultDocumentEvent(offset, length, DocumentEvent.EventType.INSERT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            evnt.addEdit(cEdit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            buffer.insert(offset, length, data, evnt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            // update bidi (possibly)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            super.insertUpdate(evnt, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            // notify the listeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            evnt.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            fireInsertUpdate(evnt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            fireUndoableEditUpdate(new UndoableEditEvent(this, evnt));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * Removes an element from this document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * <p>The element is removed from its parent element, as well as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * the text in the range identified by the element.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * element isn't associated with the document, {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * IllegalArgumentException} is thrown.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * <p>As empty branch elements are not allowed in the document, if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * element is the sole child, its parent element is removed as well,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * recursively.  This means that when replacing all the children of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * particular element, new children should be added <em>before</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * removing old children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * <p>Element removal results in two events being fired, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * {@code DocumentEvent} for changes in element structure and {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * UndoableEditEvent} for changes in document content.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * <p>If the element contains end-of-content mark (the last {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * "\n"} character in document), this character is not removed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * instead, preceding leaf element is extended to cover the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * character.  If the last leaf already ends with {@code "\n",} it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * included in content removal.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * <p>If the element is {@code null,} {@code NullPointerException} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * thrown.  If the element structure would become invalid after the removal,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * for example if the element is the document root element, {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * IllegalArgumentException} is thrown.  If the current element structure is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * invalid, {@code IllegalStateException} is thrown.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * @param  elem                      the element to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * @throws NullPointerException      if the element is {@code null}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * @throws IllegalArgumentException  if the element could not be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * @throws IllegalStateException     if the element structure is invalid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * @since  1.7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    public void removeElement(Element elem) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            removeElementImpl(elem);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    private void removeElementImpl(Element elem) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        if (elem.getDocument() != this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            throw new IllegalArgumentException("element doesn't belong to document");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        BranchElement parent = (BranchElement) elem.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        if (parent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            throw new IllegalArgumentException("can't remove the root element");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        int startOffset = elem.getStartOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        int removeFrom = startOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        int endOffset = elem.getEndOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        int removeTo = endOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        int lastEndOffset = getLength() + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        Content content = getContent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        boolean atEnd = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        boolean isComposedText = Utilities.isComposedTextElement(elem);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        if (endOffset >= lastEndOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            // element includes the last "\n" character, needs special handling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            if (startOffset <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                throw new IllegalArgumentException("can't remove the whole content");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            removeTo = lastEndOffset - 1; // last "\n" must not be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                if (content.getString(startOffset - 1, 1).charAt(0) == '\n') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                    removeFrom--; // preceding leaf ends with "\n", remove it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            } catch (BadLocationException ble) { // can't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                throw new IllegalStateException(ble);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            atEnd = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        int length = removeTo - removeFrom;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        DefaultDocumentEvent dde = new DefaultDocumentEvent(removeFrom,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                length, DefaultDocumentEvent.EventType.REMOVE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        UndoableEdit ue = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        // do not leave empty branch elements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        while (parent.getElementCount() == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            elem = parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            parent = (BranchElement) parent.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            if (parent == null) { // shouldn't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                throw new IllegalStateException("invalid element structure");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        Element[] removed = { elem };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        Element[] added = {};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        int index = parent.getElementIndex(startOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        parent.replace(index, 1, added);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        dde.addEdit(new ElementEdit(parent, index, removed, added));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        if (length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                ue = content.remove(removeFrom, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                if (ue != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                    dde.addEdit(ue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            } catch (BadLocationException ble) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                // can only happen if the element structure is severely broken
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                throw new IllegalStateException(ble);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            lastEndOffset -= length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        if (atEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            // preceding leaf element should be extended to cover orphaned "\n"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            Element prevLeaf = parent.getElement(parent.getElementCount() - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            while ((prevLeaf != null) && !prevLeaf.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                prevLeaf = prevLeaf.getElement(prevLeaf.getElementCount() - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            if (prevLeaf == null) { // shouldn't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                throw new IllegalStateException("invalid element structure");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            int prevStartOffset = prevLeaf.getStartOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            BranchElement prevParent = (BranchElement) prevLeaf.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            int prevIndex = prevParent.getElementIndex(prevStartOffset);
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   348
            Element newElem;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            newElem = createLeafElement(prevParent, prevLeaf.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                                            prevStartOffset, lastEndOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            Element[] prevRemoved = { prevLeaf };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            Element[] prevAdded = { newElem };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            prevParent.replace(prevIndex, 1, prevAdded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            dde.addEdit(new ElementEdit(prevParent, prevIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                                                    prevRemoved, prevAdded));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        postRemoveUpdate(dde);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        dde.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        fireRemoveUpdate(dde);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        if (! (isComposedText && (ue != null))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            // do not fire UndoabeEdit event for composed text edit (unsupported)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            fireUndoableEditUpdate(new UndoableEditEvent(this, dde));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * Adds a new style into the logical style hierarchy.  Style attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * resolve from bottom up so an attribute specified in a child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * will override an attribute specified in the parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * @param nm   the name of the style (must be unique within the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     *   collection of named styles).  The name may be null if the style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     *   is unnamed, but the caller is responsible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     *   for managing the reference returned as an unnamed style can't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     *   be fetched by name.  An unnamed style may be useful for things
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     *   like character attribute overrides such as found in a style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     *   run.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * @param parent the parent style.  This may be null if unspecified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     *   attributes need not be resolved in some other style.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * @return the style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    public Style addStyle(String nm, Style parent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        StyleContext styles = (StyleContext) getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        return styles.addStyle(nm, parent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * Removes a named style previously added to the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * @param nm  the name of the style to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    public void removeStyle(String nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        StyleContext styles = (StyleContext) getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        styles.removeStyle(nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * Fetches a named style previously added.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * @param nm  the name of the style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * @return the style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    public Style getStyle(String nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        StyleContext styles = (StyleContext) getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        return styles.getStyle(nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     * Fetches the list of of style names.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * @return all the style names
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    public Enumeration<?> getStyleNames() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        return ((StyleContext) getAttributeContext()).getStyleNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * Sets the logical style to use for the paragraph at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     * given position.  If attributes aren't explicitly set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     * for character and paragraph attributes they will resolve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * through the logical style assigned to the paragraph, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     * in turn may resolve through some hierarchy completely
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * independent of the element hierarchy in the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * This method is thread safe, although most Swing methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * are not. Please see
20455
f6f9a0c2796b 8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents: 20158
diff changeset
   429
     * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
10316
8d1ca7d93fb2 7075563: Broken link in "javax.swing.SwingWorker"
rupashka
parents: 7668
diff changeset
   430
     * in Swing</A> for more information.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   432
     * @param pos the offset from the start of the document &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * @param s  the logical style to assign to the paragraph, null if none
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    public void setLogicalStyle(int pos, Style s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        Element paragraph = getParagraphElement(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        if ((paragraph != null) && (paragraph instanceof AbstractElement)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                StyleChangeUndoableEdit edit = new StyleChangeUndoableEdit((AbstractElement)paragraph, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                ((AbstractElement)paragraph).setResolveParent(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                int p0 = paragraph.getStartOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                int p1 = paragraph.getEndOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                DefaultDocumentEvent e =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                  new DefaultDocumentEvent(p0, p1 - p0, DocumentEvent.EventType.CHANGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                e.addEdit(edit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                e.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                fireChangedUpdate(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                fireUndoableEditUpdate(new UndoableEditEvent(this, e));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * Fetches the logical style assigned to the paragraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * represented by the given position.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * @param p the location to translate to a paragraph
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   461
     *  and determine the logical style assigned &gt;= 0.  This
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     *  is an offset from the start of the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * @return the style, null if none
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    public Style getLogicalStyle(int p) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        Style s = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        Element paragraph = getParagraphElement(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        if (paragraph != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            AttributeSet a = paragraph.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            AttributeSet parent = a.getResolveParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            if (parent instanceof Style) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                s = (Style) parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * Sets attributes for some part of the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * A write lock is held by this operation while changes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * are being made, and a DocumentEvent is sent to the listeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * after the change has been successfully completed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * This method is thread safe, although most Swing methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     * are not. Please see
20455
f6f9a0c2796b 8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents: 20158
diff changeset
   486
     * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
10316
8d1ca7d93fb2 7075563: Broken link in "javax.swing.SwingWorker"
rupashka
parents: 7668
diff changeset
   487
     * in Swing</A> for more information.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   489
     * @param offset the offset in the document &gt;= 0
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   490
     * @param length the length &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     * @param s the attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * @param replace true if the previous attributes should be replaced
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     *  before setting the new attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    public void setCharacterAttributes(int offset, int length, AttributeSet s, boolean replace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        if (length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            DefaultDocumentEvent changes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                new DefaultDocumentEvent(offset, length, DocumentEvent.EventType.CHANGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            // split elements that need it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            buffer.change(offset, length, changes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            AttributeSet sCopy = s.copyAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            // PENDING(prinz) - this isn't a very efficient way to iterate
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   510
            int lastEnd;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            for (int pos = offset; pos < (offset + length); pos = lastEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                Element run = getCharacterElement(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                lastEnd = run.getEndOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                if (pos == lastEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                    // offset + length beyond length of document, bail.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                MutableAttributeSet attr = (MutableAttributeSet) run.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                changes.addEdit(new AttributeUndoableEdit(run, sCopy, replace));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                if (replace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                    attr.removeAttributes(attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                attr.addAttributes(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            changes.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            fireChangedUpdate(changes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            fireUndoableEditUpdate(new UndoableEditEvent(this, changes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * Sets attributes for a paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     * This method is thread safe, although most Swing methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * are not. Please see
20455
f6f9a0c2796b 8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents: 20158
diff changeset
   539
     * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
10316
8d1ca7d93fb2 7075563: Broken link in "javax.swing.SwingWorker"
rupashka
parents: 7668
diff changeset
   540
     * in Swing</A> for more information.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   542
     * @param offset the offset into the paragraph &gt;= 0
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   543
     * @param length the number of characters affected &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     * @param s the attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
     * @param replace whether to replace existing attributes, or merge them
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    public void setParagraphAttributes(int offset, int length, AttributeSet s,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                                       boolean replace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            DefaultDocumentEvent changes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                new DefaultDocumentEvent(offset, length, DocumentEvent.EventType.CHANGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            AttributeSet sCopy = s.copyAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            // PENDING(prinz) - this assumes a particular element structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            Element section = getDefaultRootElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            int index0 = section.getElementIndex(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            int index1 = section.getElementIndex(offset + ((length > 0) ? length - 1 : 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            boolean isI18N = Boolean.TRUE.equals(getProperty(I18NProperty));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            boolean hasRuns = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            for (int i = index0; i <= index1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                Element paragraph = section.getElement(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                MutableAttributeSet attr = (MutableAttributeSet) paragraph.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                changes.addEdit(new AttributeUndoableEdit(paragraph, sCopy, replace));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                if (replace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                    attr.removeAttributes(attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                attr.addAttributes(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                if (isI18N && !hasRuns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                    hasRuns = (attr.getAttribute(TextAttribute.RUN_DIRECTION) != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            if (hasRuns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                updateBidi( changes );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            changes.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            fireChangedUpdate(changes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            fireUndoableEditUpdate(new UndoableEditEvent(this, changes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     * Gets the paragraph element at the offset <code>pos</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     * A paragraph consists of at least one child Element, which is usually
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
     * a leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
     *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   592
     * @param pos the starting offset &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     * @return the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    public Element getParagraphElement(int pos) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   596
        Element e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        for (e = getDefaultRootElement(); ! e.isLeaf(); ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            int index = e.getElementIndex(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            e = e.getElement(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        if(e != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
            return e.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * Gets a character element based on a position.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
   609
     * @param pos the position in the document &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * @return the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    public Element getCharacterElement(int pos) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   613
        Element e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        for (e = getDefaultRootElement(); ! e.isLeaf(); ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            int index = e.getElementIndex(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            e = e.getElement(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    // --- local methods -------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * Updates document structure as a result of text insertion.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * will happen within a write lock.  This implementation simply
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * parses the inserted content for line breaks and builds up a set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * of instructions for the element buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     * @param chng a description of the document change
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * @param attr the attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        int offset = chng.getOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        int length = chng.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        if (attr == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            attr = SimpleAttributeSet.EMPTY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        // Paragraph attributes should come from point after insertion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        // You really only notice this when inserting at a paragraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        // boundary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        Element paragraph = getParagraphElement(offset + length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        AttributeSet pattr = paragraph.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        // Character attributes should come from actual insertion point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        Element pParagraph = getParagraphElement(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        Element run = pParagraph.getElement(pParagraph.getElementIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                                            (offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        int endOffset = offset + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        boolean insertingAtBoundry = (run.getEndOffset() == endOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        AttributeSet cattr = run.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            Segment s = new Segment();
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   654
            Vector<ElementSpec> parseBuffer = new Vector<ElementSpec>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            ElementSpec lastStartSpec = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            boolean insertingAfterNewline = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            short lastStartDirection = ElementSpec.OriginateDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            // Check if the previous character was a newline.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            if (offset > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                getText(offset - 1, 1, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                if (s.array[s.offset] == '\n') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                    // Inserting after a newline.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    insertingAfterNewline = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                    lastStartDirection = createSpecsForInsertAfterNewline
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                                  (paragraph, pParagraph, pattr, parseBuffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                                   offset, endOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                    for(int counter = parseBuffer.size() - 1; counter >= 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                        counter--) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   669
                        ElementSpec spec = parseBuffer.elementAt(counter);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                        if(spec.getType() == ElementSpec.StartTagType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                            lastStartSpec = spec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            // If not inserting after a new line, pull the attributes for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            // new paragraphs from the paragraph under the insertion point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            if(!insertingAfterNewline)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                pattr = pParagraph.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            getText(offset, length, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            char[] txt = s.array;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            int n = s.offset + s.count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            int lastOffset = s.offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            for (int i = s.offset; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                if (txt[i] == '\n') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                    int breakOffset = i + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                    parseBuffer.addElement(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                        new ElementSpec(attr, ElementSpec.ContentType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                                               breakOffset - lastOffset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                    parseBuffer.addElement(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                        new ElementSpec(null, ElementSpec.EndTagType));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    lastStartSpec = new ElementSpec(pattr, ElementSpec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                                                   StartTagType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                    parseBuffer.addElement(lastStartSpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                    lastOffset = breakOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            if (lastOffset < n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                parseBuffer.addElement(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                    new ElementSpec(attr, ElementSpec.ContentType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                                           n - lastOffset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   707
            ElementSpec first = parseBuffer.firstElement();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            int docLength = getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            // Check for join previous of first content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            if(first.getType() == ElementSpec.ContentType &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
               cattr.isEqual(attr)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                first.setDirection(ElementSpec.JoinPreviousDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            // Do a join fracture/next for last start spec if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            if(lastStartSpec != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                if(insertingAfterNewline) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                    lastStartSpec.setDirection(lastStartDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                // Join to the fracture if NOT inserting at the end
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                // (fracture only happens when not inserting at end of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                // paragraph).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                else if(pParagraph.getEndOffset() != endOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                    lastStartSpec.setDirection(ElementSpec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                                               JoinFractureDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                // Join to next if parent of pParagraph has another
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                // element after pParagraph, and it isn't a leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                    Element parent = pParagraph.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                    int pParagraphIndex = parent.getElementIndex(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                    if((pParagraphIndex + 1) < parent.getElementCount() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                       !parent.getElement(pParagraphIndex + 1).isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                        lastStartSpec.setDirection(ElementSpec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                                                   JoinNextDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            // Do a JoinNext for last spec if it is content, it doesn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            // already have a direction set, no new paragraphs have been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            // inserted or a new paragraph has been inserted and its join
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
            // direction isn't originate, and the element at endOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
            // is a leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
            if(insertingAtBoundry && endOffset < docLength) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   748
                ElementSpec last = parseBuffer.lastElement();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                if(last.getType() == ElementSpec.ContentType &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                   last.getDirection() != ElementSpec.JoinPreviousDirection &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                   ((lastStartSpec == null && (paragraph == pParagraph ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                                               insertingAfterNewline)) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                    (lastStartSpec != null && lastStartSpec.getDirection() !=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                     ElementSpec.OriginateDirection))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                    Element nextRun = paragraph.getElement(paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                                           getElementIndex(endOffset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                    // Don't try joining to a branch!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    if(nextRun.isLeaf() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                       attr.isEqual(nextRun.getAttributes())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                        last.setDirection(ElementSpec.JoinNextDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            // If not inserting at boundary and there is going to be a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            // fracture, then can join next on last content if cattr
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            // matches the new attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            else if(!insertingAtBoundry && lastStartSpec != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                    lastStartSpec.getDirection() ==
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                    ElementSpec.JoinFractureDirection) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   770
                ElementSpec last = parseBuffer.lastElement();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                if(last.getType() == ElementSpec.ContentType &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                   last.getDirection() != ElementSpec.JoinPreviousDirection &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                   attr.isEqual(cattr)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                    last.setDirection(ElementSpec.JoinNextDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            // Check for the composed text element. If it is, merge the character attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            // into this element as well.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            if (Utilities.isComposedTextAttributeDefined(attr)) {
5763
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   781
                MutableAttributeSet mattr = (MutableAttributeSet) attr;
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   782
                mattr.addAttributes(cattr);
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   783
                mattr.addAttribute(AbstractDocument.ElementNameAttribute,
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   784
                        AbstractDocument.ContentElementName);
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   785
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   786
                // Assure that the composed text element is named properly
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   787
                // and doesn't have the CR attribute defined.
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   788
                mattr.addAttribute(StyleConstants.NameAttribute,
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   789
                        AbstractDocument.ContentElementName);
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   790
                if (mattr.isDefined(IMPLIED_CR)) {
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   791
                    mattr.removeAttribute(IMPLIED_CR);
9a942d6fb0aa 6636983: Japanese text does not display correctly in a JEditorPane
rupashka
parents: 5506
diff changeset
   792
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
            ElementSpec[] spec = new ElementSpec[parseBuffer.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            parseBuffer.copyInto(spec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            buffer.insert(offset, length, spec, chng);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        } catch (BadLocationException bl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        super.insertUpdate( chng, attr );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     * This is called by insertUpdate when inserting after a new line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
     * It generates, in <code>parseBuffer</code>, ElementSpecs that will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
     * position the stack in <code>paragraph</code>.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
     * It returns the direction the last StartSpec should have (this don't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
     * necessarily create the last start spec).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    short createSpecsForInsertAfterNewline(Element paragraph,
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   812
            Element pParagraph, AttributeSet pattr, Vector<ElementSpec> parseBuffer,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                                                 int offset, int endOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        // Need to find the common parent of pParagraph and paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
        if(paragraph.getParentElement() == pParagraph.getParentElement()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            // The simple (and common) case that pParagraph and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            // paragraph have the same parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            ElementSpec spec = new ElementSpec(pattr, ElementSpec.EndTagType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            parseBuffer.addElement(spec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            spec = new ElementSpec(pattr, ElementSpec.StartTagType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            parseBuffer.addElement(spec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            if(pParagraph.getEndOffset() != endOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                return ElementSpec.JoinFractureDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            Element parent = pParagraph.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
            if((parent.getElementIndex(offset) + 1) < parent.getElementCount())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                return ElementSpec.JoinNextDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            // Will only happen for text with more than 2 levels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            // Find the common parent of a paragraph and pParagraph
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   832
            Vector<Element> leftParents = new Vector<Element>();
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   833
            Vector<Element> rightParents = new Vector<Element>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
            Element e = pParagraph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
            while(e != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                leftParents.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                e = e.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            e = paragraph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
            int leftIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
            while(e != null && (leftIndex = leftParents.indexOf(e)) == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                rightParents.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                e = e.getParentElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            if(e != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                // e identifies the common parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                // Build the ends.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                for(int counter = 0; counter < leftIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                    counter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                    parseBuffer.addElement(new ElementSpec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                                              (null, ElementSpec.EndTagType));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                // And the starts.
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   854
                ElementSpec spec;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                for(int counter = rightParents.size() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                    counter >= 0; counter--) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   857
                    spec = new ElementSpec(rightParents.elementAt(counter).getAttributes(),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                                   ElementSpec.StartTagType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    if(counter > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                        spec.setDirection(ElementSpec.JoinNextDirection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                    parseBuffer.addElement(spec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                // If there are right parents, then we generated starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                // down the right subtree and there will be an element to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                // join to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                if(rightParents.size() > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                    return ElementSpec.JoinNextDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                // No right subtree, e.getElement(endOffset) is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                // leaf. There will be a facture.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                return ElementSpec.JoinFractureDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
            // else: Could throw an exception here, but should never get here!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        return ElementSpec.OriginateDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     * Updates document structure as a result of text removal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * @param chng a description of the document change
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
    protected void removeUpdate(DefaultDocumentEvent chng) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        super.removeUpdate(chng);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
        buffer.remove(chng.getOffset(), chng.getLength(), chng);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
     * Creates the root element to be used to represent the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
     * default document structure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
     * @return the element base
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    protected AbstractElement createDefaultRoot() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        // grabs a write-lock for this initialization and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
        // abandon it during initialization so in normal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
        // operation we can detect an illegitimate attempt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        // to mutate attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        BranchElement section = new SectionElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        BranchElement paragraph = new BranchElement(section, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        LeafElement brk = new LeafElement(paragraph, null, 0, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
        Element[] buff = new Element[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        buff[0] = brk;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        paragraph.replace(0, 0, buff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        buff[0] = paragraph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        section.replace(0, 0, buff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        return section;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
     * Gets the foreground color from an attribute set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
     * @param attr the attribute set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     * @return the color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    public Color getForeground(AttributeSet attr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
        StyleContext styles = (StyleContext) getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
        return styles.getForeground(attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
     * Gets the background color from an attribute set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
     * @param attr the attribute set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
     * @return the color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
    public Color getBackground(AttributeSet attr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        StyleContext styles = (StyleContext) getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        return styles.getBackground(attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
     * Gets the font from an attribute set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
     * @param attr the attribute set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
     * @return the font
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    public Font getFont(AttributeSet attr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        StyleContext styles = (StyleContext) getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
        return styles.getFont(attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
     * Called when any of this document's styles have changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
     * Subclasses may wish to be intelligent about what gets damaged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     * @param style The Style that has changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
    protected void styleChanged(Style style) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        // Only propagate change updated if have content
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
        if (getLength() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
            // lazily create a ChangeUpdateRunnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            if (updateRunnable == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
                updateRunnable = new ChangeUpdateRunnable();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            // We may get a whole batch of these at once, so only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            // queue the runnable if it is not already pending
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
            synchronized(updateRunnable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
                if (!updateRunnable.isPending) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
                    SwingUtilities.invokeLater(updateRunnable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
                    updateRunnable.isPending = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
     * Adds a document listener for notification of any changes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
     * @param listener the listener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
     * @see Document#addDocumentListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    public void addDocumentListener(DocumentListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
        synchronized(listeningStyles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
            int oldDLCount = listenerList.getListenerCount
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                                          (DocumentListener.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
            super.addDocumentListener(listener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            if (oldDLCount == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                if (styleContextChangeListener == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
                    styleContextChangeListener =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
                                      createStyleContextChangeListener();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
                if (styleContextChangeListener != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                    StyleContext styles = (StyleContext)getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                    List<ChangeListener> staleListeners =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                        AbstractChangeHandler.getStaleListeners(styleContextChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
                    for (ChangeListener l: staleListeners) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                        styles.removeChangeListener(l);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                    styles.addChangeListener(styleContextChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
                updateStylesListeningTo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
     * Removes a document listener.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
     * @param listener the listener
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
     * @see Document#removeDocumentListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    public void removeDocumentListener(DocumentListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        synchronized(listeningStyles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
            super.removeDocumentListener(listener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            if (listenerList.getListenerCount(DocumentListener.class) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
                for (int counter = listeningStyles.size() - 1; counter >= 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                     counter--) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1013
                    listeningStyles.elementAt(counter).
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                                    removeChangeListener(styleChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                listeningStyles.removeAllElements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
                if (styleContextChangeListener != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                    StyleContext styles = (StyleContext)getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
                    styles.removeChangeListener(styleContextChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
     * Returns a new instance of StyleChangeHandler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    ChangeListener createStyleChangeListener() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        return new StyleChangeHandler(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
     * Returns a new instance of StyleContextChangeHandler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
    ChangeListener createStyleContextChangeListener() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        return new StyleContextChangeHandler(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
     * Adds a ChangeListener to new styles, and removes ChangeListener from
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
     * old styles.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
    void updateStylesListeningTo() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
        synchronized(listeningStyles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
            StyleContext styles = (StyleContext)getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            if (styleChangeListener == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                styleChangeListener = createStyleChangeListener();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            if (styleChangeListener != null && styles != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
                Enumeration styleNames = styles.getStyleNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                Vector v = (Vector)listeningStyles.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                listeningStyles.removeAllElements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
                List<ChangeListener> staleListeners =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                    AbstractChangeHandler.getStaleListeners(styleChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                while (styleNames.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                    String name = (String)styleNames.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                    Style aStyle = styles.getStyle(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                    int index = v.indexOf(aStyle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                    listeningStyles.addElement(aStyle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                    if (index == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
                        for (ChangeListener l: staleListeners) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
                            aStyle.removeChangeListener(l);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                        aStyle.addChangeListener(styleChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                        v.removeElementAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                for (int counter = v.size() - 1; counter >= 0; counter--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                    Style aStyle = (Style)v.elementAt(counter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                    aStyle.removeChangeListener(styleChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                if (listeningStyles.size() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                    styleChangeListener = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
    private void readObject(ObjectInputStream s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            throws ClassNotFoundException, IOException {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1083
        listeningStyles = new Vector<Style>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
        s.defaultReadObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        // Reinstall style listeners.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        if (styleContextChangeListener == null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            listenerList.getListenerCount(DocumentListener.class) > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
            styleContextChangeListener = createStyleContextChangeListener();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
            if (styleContextChangeListener != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                StyleContext styles = (StyleContext)getAttributeContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                styles.addChangeListener(styleContextChangeListener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
            updateStylesListeningTo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
    // --- member variables -----------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
     * The default size of the initial content buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
    public static final int BUFFER_SIZE_DEFAULT = 4096;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
    protected ElementBuffer buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
    /** Styles listening to. */
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1107
    private transient Vector<Style> listeningStyles;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
    /** Listens to Styles. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
    private transient ChangeListener styleChangeListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
    /** Listens to Styles. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
    private transient ChangeListener styleContextChangeListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
    /** Run to create a change event for the document */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
    private transient ChangeUpdateRunnable updateRunnable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
     * Default root element for a document... maps out the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
     * paragraphs/lines contained.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
     * <strong>Warning:</strong>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
     * Serialized objects of this class will not be compatible with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
     * future Swing releases. The current serialization support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
     * appropriate for short term storage or RMI between applications running
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
     * the same version of Swing.  As of 1.4, support for long term storage
20458
f2423fb3fd19 8025840: Fix all the doclint warnings about trademark
cl
parents: 20455
diff changeset
  1127
     * of all JavaBeans&trade;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
     * has been added to the <code>java.beans</code> package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
     * Please see {@link java.beans.XMLEncoder}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    protected class SectionElement extends BranchElement {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
         * Creates a new SectionElement.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
        public SectionElement() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
            super(null, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
         * Gets the name of the element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
         * @return the name
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
        public String getName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
            return SectionElementName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
     * Specification for building elements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
     * <strong>Warning:</strong>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
     * Serialized objects of this class will not be compatible with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
     * future Swing releases. The current serialization support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
     * appropriate for short term storage or RMI between applications running
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
     * the same version of Swing.  As of 1.4, support for long term storage
20458
f2423fb3fd19 8025840: Fix all the doclint warnings about trademark
cl
parents: 20455
diff changeset
  1158
     * of all JavaBeans&trade;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
     * has been added to the <code>java.beans</code> package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
     * Please see {@link java.beans.XMLEncoder}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    public static class ElementSpec {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
         * A possible value for getType.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
         * that this record type is a start tag and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
         * represents markup that specifies the start
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
         * of an element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
        public static final short StartTagType = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
         * A possible value for getType.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
         * that this record type is a end tag and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
         * represents markup that specifies the end
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
         * of an element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        public static final short EndTagType = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
         * A possible value for getType.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
         * that this record type represents content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
        public static final short ContentType = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
         * A possible value for getDirection.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
         * that the data associated with this record should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
         * be joined to what precedes it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
        public static final short JoinPreviousDirection = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
         * A possible value for getDirection.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
         * that the data associated with this record should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
         * be joined to what follows it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
        public static final short JoinNextDirection = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
         * A possible value for getDirection.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
         * that the data associated with this record should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
         * be used to originate a new element.  This would be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
         * the normal value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
        public static final short OriginateDirection = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
         * A possible value for getDirection.  This specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
         * that the data associated with this record should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
         * be joined to the fractured element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        public static final short JoinFractureDirection = 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
         * Constructor useful for markup when the markup will not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
         * be stored in the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
         * @param a the attributes for the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
         * @param type the type of the element (StartTagType, EndTagType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
         *  ContentType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
        public ElementSpec(AttributeSet a, short type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
            this(a, type, null, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
         * Constructor for parsing inside the document when
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
         * the data has already been added, but len information
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
         * is needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
         * @param a the attributes for the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
         * @param type the type of the element (StartTagType, EndTagType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
         *  ContentType)
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1236
         * @param len the length &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
        public ElementSpec(AttributeSet a, short type, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
            this(a, type, null, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
         * Constructor for creating a spec externally for batch
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
         * input of content and markup into the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
         * @param a the attributes for the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
         * @param type the type of the element (StartTagType, EndTagType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
         *  ContentType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
         * @param txt the text for the element
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1250
         * @param offs the offset into the text &gt;= 0
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1251
         * @param len the length of the text &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
        public ElementSpec(AttributeSet a, short type, char[] txt,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                                  int offs, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            attr = a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
            this.type = type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
            this.data = txt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
            this.offs = offs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
            this.len = len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
            this.direction = OriginateDirection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
         * Sets the element type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
         * @param type the type of the element (StartTagType, EndTagType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
         *  ContentType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
        public void setType(short type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
            this.type = type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
         * Gets the element type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
         * @return  the type of the element (StartTagType, EndTagType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
         *  ContentType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
        public short getType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
            return type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
         * Sets the direction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
         * @param direction the direction (JoinPreviousDirection,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
         *   JoinNextDirection)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
        public void setDirection(short direction) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
            this.direction = direction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
         * Gets the direction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
         * @return the direction (JoinPreviousDirection, JoinNextDirection)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
        public short getDirection() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
            return direction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
         * Gets the element attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
         * @return the attribute set
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
        public AttributeSet getAttributes() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
            return attr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
         * Gets the array of characters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
         * @return the array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
        public char[] getArray() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
            return data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
         * Gets the starting offset.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
         *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1324
         * @return the offset &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
        public int getOffset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
            return offs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
         * Gets the length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
         *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1333
         * @return the length &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
        public int getLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
         * Converts the element to a string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
         * @return the string
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
        public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
            String tlbl = "??";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
            String plbl = "??";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
            switch(type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
            case StartTagType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
                tlbl = "StartTag";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
            case ContentType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
                tlbl = "Content";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
            case EndTagType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
                tlbl = "EndTag";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
            switch(direction) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
            case JoinPreviousDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
                plbl = "JoinPrevious";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
            case JoinNextDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
                plbl = "JoinNext";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
            case OriginateDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
                plbl = "Originate";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
            case JoinFractureDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                plbl = "Fracture";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
            return tlbl + ":" + plbl + ":" + getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
        private AttributeSet attr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
        private int len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        private short type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        private short direction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        private int offs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
        private char[] data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
     * Class to manage changes to the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
     * hierarchy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
     * <strong>Warning:</strong>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
     * Serialized objects of this class will not be compatible with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
     * future Swing releases. The current serialization support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
     * appropriate for short term storage or RMI between applications running
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
     * the same version of Swing.  As of 1.4, support for long term storage
20458
f2423fb3fd19 8025840: Fix all the doclint warnings about trademark
cl
parents: 20455
diff changeset
  1393
     * of all JavaBeans&trade;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
     * has been added to the <code>java.beans</code> package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
     * Please see {@link java.beans.XMLEncoder}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
    public class ElementBuffer implements Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
         * Creates a new ElementBuffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
         * @param root the root element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
         * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
        public ElementBuffer(Element root) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            this.root = root;
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1407
            changes = new Vector<ElemChanges>();
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1408
            path = new Stack<ElemChanges>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
         * Gets the root element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
         * @return the root element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        public Element getRootElement() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
            return root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
         * Inserts new content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
         *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1423
         * @param offset the starting offset &gt;= 0
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1424
         * @param length the length &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
         * @param data the data to insert
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
         * @param de the event capturing this edit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
        public void insert(int offset, int length, ElementSpec[] data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                                 DefaultDocumentEvent de) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
            if (length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
                // Nothing was inserted, no structure change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
            insertOp = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
            beginEdits(offset, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
            insertUpdate(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
            endEdits(de);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
            insertOp = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
        void create(int length, ElementSpec[] data, DefaultDocumentEvent de) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
            insertOp = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
            beginEdits(offset, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
            // PENDING(prinz) this needs to be fixed to create a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            // root element as well, but requires changes to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
            // DocumentEvent to inform the views that there is a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
            // root element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
            // Recreate the ending fake element to have the correct offsets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
            Element elem = root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
            int index = elem.getElementIndex(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
            while (! elem.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                Element child = elem.getElement(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
                push(elem, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                elem = child;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
                index = elem.getElementIndex(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            }
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1460
            ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
            Element child = ec.parent.getElement(ec.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
            ec.added.addElement(createLeafElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                                child.getAttributes(), getLength(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                                child.getEndOffset()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
            ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
            while (path.size() > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
                pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
            int n = data.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
            // Reset the root elements attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
            AttributeSet newAttrs = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
            if (n > 0 && data[0].getType() == ElementSpec.StartTagType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
                newAttrs = data[0].getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
            if (newAttrs == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
                newAttrs = SimpleAttributeSet.EMPTY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
            MutableAttributeSet attr = (MutableAttributeSet)root.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                                       getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
            de.addEdit(new AttributeUndoableEdit(root, newAttrs, true));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
            attr.removeAttributes(attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
            attr.addAttributes(newAttrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
            // fold in the specified subtree
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
            for (int i = 1; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
                insertElement(data[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
            // pop the remaining path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
            while (path.size() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
                pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
            endEdits(de);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
            insertOp = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
         * Removes content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
         *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1503
         * @param offset the starting offset &gt;= 0
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1504
         * @param length the length &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
         * @param de the event capturing this edit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
        public void remove(int offset, int length, DefaultDocumentEvent de) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
            beginEdits(offset, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
            removeUpdate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
            endEdits(de);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
         * Changes content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
         *
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1516
         * @param offset the starting offset &gt;= 0
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 10316
diff changeset
  1517
         * @param length the length &gt;= 0
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
         * @param de the event capturing this edit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
        public void change(int offset, int length, DefaultDocumentEvent de) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
            beginEdits(offset, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
            changeUpdate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
            endEdits(de);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
         * Inserts an update into the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
         * @param data the elements to insert
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
        protected void insertUpdate(ElementSpec[] data) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
            // push the path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
            Element elem = root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
            int index = elem.getElementIndex(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
            while (! elem.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                Element child = elem.getElement(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
                push(elem, (child.isLeaf() ? index : index+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
                elem = child;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
                index = elem.getElementIndex(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
            // Build a copy of the original path.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
            insertPath = new ElemChanges[path.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
            path.copyInto(insertPath);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
            // Haven't created the fracture yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
            createdFracture = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
            // Insert the first content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
            int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
            recreateLeafs = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
            if(data[0].getType() == ElementSpec.ContentType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
                insertFirstContent(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
                pos += data[0].getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
                i = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
                fractureDeepestLeaf(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
                i = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
            // fold in the specified subtree
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
            int n = data.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
            for (; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
                insertElement(data[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
            // Fracture, if we haven't yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
            if(!createdFracture)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
                fracture(-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
            // pop the remaining path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
            while (path.size() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
                pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
            // Offset the last index if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
            if(offsetLastIndex && offsetLastIndexOnReplace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
                insertPath[insertPath.length - 1].index++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
            // Make sure an edit is going to be created for each of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
            // original path items that have a change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
            for(int counter = insertPath.length - 1; counter >= 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                counter--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
                ElemChanges change = insertPath[counter];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
                if(change.parent == fracturedParent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
                    change.added.addElement(fracturedChild);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
                if((change.added.size() > 0 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
                    change.removed.size() > 0) && !changes.contains(change)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
                    // PENDING(sky): Do I need to worry about order here?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
                    changes.addElement(change);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
            // An insert at 0 with an initial end implies some elements
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
            // will have no children (the bottomost leaf would have length 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
            // this will find what element need to be removed and remove it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
            if (offset == 0 && fracturedParent != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
                data[0].getType() == ElementSpec.EndTagType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
                int counter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
                while (counter < data.length &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
                       data[counter].getType() == ElementSpec.EndTagType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
                    counter++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
                ElemChanges change = insertPath[insertPath.length -
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
                                               counter - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
                change.removed.insertElementAt(change.parent.getElement
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
                                               (--change.index), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
         * Updates the element structure in response to a removal from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
         * associated sequence in the document.  Any elements consumed by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
         * span of the removal are removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
        protected void removeUpdate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
            removeElements(root, offset, offset + length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
         * Updates the element structure in response to a change in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
         * document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
        protected void changeUpdate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
            boolean didEnd = split(offset, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
            if (! didEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
                // need to do the other end
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
                while (path.size() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
                    pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
                split(offset + length, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
            while (path.size() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
                pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
        boolean split(int offs, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
            boolean splitEnd = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
            // push the path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
            Element e = root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
            int index = e.getElementIndex(offs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
            while (! e.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
                push(e, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
                e = e.getElement(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
                index = e.getElementIndex(offs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1652
            ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
            Element child = ec.parent.getElement(ec.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
            // make sure there is something to do... if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
            // offset is already at a boundary then there is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
            // nothing to do.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
            if (child.getStartOffset() < offs && offs < child.getEndOffset()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
                // we need to split, now see if the other end is within
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
                // the same parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
                int index0 = ec.index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
                int index1 = index0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
                if (((offs + len) < ec.parent.getEndOffset()) && (len != 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
                    // it's a range split in the same parent
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
                    index1 = ec.parent.getElementIndex(offs+len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
                    if (index1 == index0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
                        // it's a three-way split
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
                        ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
                        e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
                                              child.getStartOffset(), offs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
                        ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
                        e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
                                          offs, offs + len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
                        ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
                        e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
                                              offs + len, child.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
                        ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
                        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
                        child = ec.parent.getElement(index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
                        if ((offs + len) == child.getStartOffset()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
                            // end is already on a boundary
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
                            index1 = index0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
                    splitEnd = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
                // split the first location
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
                pos = offs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
                child = ec.parent.getElement(index0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
                ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
                e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
                                      child.getStartOffset(), pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
                ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
                e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
                                      pos, child.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
                ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
                // pick up things in the middle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
                for (int i = index0 + 1; i < index1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
                    child = ec.parent.getElement(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
                    ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
                    ec.added.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
                if (index1 != index0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
                    child = ec.parent.getElement(index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
                    pos = offs + len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
                    ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
                    e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
                                          child.getStartOffset(), pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
                    ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
                    e = createLeafElement(ec.parent, child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
                                          pos, child.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
                    ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
            return splitEnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
         * Creates the UndoableEdit record for the edits made
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
         * in the buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
        void endEdits(DefaultDocumentEvent de) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
            int n = changes.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
            for (int i = 0; i < n; i++) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1728
                ElemChanges ec = changes.elementAt(i);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
                Element[] removed = new Element[ec.removed.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
                ec.removed.copyInto(removed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
                Element[] added = new Element[ec.added.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
                ec.added.copyInto(added);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
                int index = ec.index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
                ((BranchElement) ec.parent).replace(index, removed.length, added);
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1735
                ElementEdit ee = new ElementEdit(ec.parent, index, removed, added);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
                de.addEdit(ee);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
            changes.removeAllElements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
            path.removeAllElements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
            for (int i = 0; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
                ElemChanges ec = (ElemChanges) changes.elementAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
                System.err.print("edited: " + ec.parent + " at: " + ec.index +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
                    " removed " + ec.removed.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
                if (ec.removed.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
                    int r0 = ((Element) ec.removed.firstElement()).getStartOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
                    int r1 = ((Element) ec.removed.lastElement()).getEndOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
                    System.err.print("[" + r0 + "," + r1 + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
                System.err.print(" added " + ec.added.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
                if (ec.added.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
                    int p0 = ((Element) ec.added.firstElement()).getStartOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
                    int p1 = ((Element) ec.added.lastElement()).getEndOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
                    System.err.print("[" + p0 + "," + p1 + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
                System.err.println("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
            */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
         * Initialize the buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
        void beginEdits(int offset, int length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
            this.offset = offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
            this.length = length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
            this.endOffset = offset + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
            pos = offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
            if (changes == null) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1772
                changes = new Vector<ElemChanges>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
                changes.removeAllElements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
            if (path == null) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1777
                path = new Stack<ElemChanges>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
                path.removeAllElements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
            fracturedParent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
            fracturedChild = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
            offsetLastIndex = offsetLastIndexOnReplace = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
         * Pushes a new element onto the stack that represents
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
         * the current path.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
         * @param record Whether or not the push should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
         *  recorded as an element change or not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
         * @param isFracture true if pushing on an element that was created
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
         * as the result of a fracture.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
        void push(Element e, int index, boolean isFracture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
            ElemChanges ec = new ElemChanges(e, index, isFracture);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
            path.push(ec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
        void push(Element e, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
            push(e, index, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
        void pop() {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1804
            ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
            path.pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
            if ((ec.added.size() > 0) || (ec.removed.size() > 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
                changes.addElement(ec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
            } else if (! path.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
                Element e = ec.parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
                if(e.getElementCount() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
                    // if we pushed a branch element that didn't get
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
                    // used, make sure its not marked as having been added.
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1813
                    ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
                    ec.added.removeElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
         * move the current offset forward by n.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
        void advance(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
            pos += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
        void insertElement(ElementSpec es) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1827
            ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
            switch(es.getType()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
            case ElementSpec.StartTagType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
                switch(es.getDirection()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
                case ElementSpec.JoinNextDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
                    // Don't create a new element, use the existing one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
                    // at the specified location.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
                    Element parent = ec.parent.getElement(ec.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
                    if(parent.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
                        // This happens if inserting into a leaf, followed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
                        // by a join next where next sibling is not a leaf.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
                        if((ec.index + 1) < ec.parent.getElementCount())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
                            parent = ec.parent.getElement(ec.index + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
                        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
                            throw new StateInvariantError("Join next to leaf");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
                    // Not really a fracture, but need to treat it like
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
                    // one so that content join next will work correctly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
                    // We can do this because there will never be a join
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
                    // next followed by a join fracture.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
                    push(parent, 0, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
                case ElementSpec.JoinFractureDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
                    if(!createdFracture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
                        // Should always be something on the stack!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
                        fracture(path.size() - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
                    // If parent isn't a fracture, fracture will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
                    // fracturedChild.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
                    if(!ec.isFracture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
                        push(fracturedChild, 0, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
                        // Parent is a fracture, use 1st element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
                        push(ec.parent.getElement(0), 0, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
                    Element belem = createBranchElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
                                                        es.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
                    ec.added.addElement(belem);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
                    push(belem, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
            case ElementSpec.EndTagType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
                pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
            case ElementSpec.ContentType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
              int len = es.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
                if (es.getDirection() != ElementSpec.JoinNextDirection) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
                    Element leaf = createLeafElement(ec.parent, es.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
                                                     pos, pos + len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
                    ec.added.addElement(leaf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
                    // JoinNext on tail is only applicable if last element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
                    // and attributes come from that of first element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
                    // With a little extra testing it would be possible
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
                    // to NOT due this again, as more than likely fracture()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
                    // created this element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
                    if(!ec.isFracture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
                        Element first = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
                        if(insertPath != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
                            for(int counter = insertPath.length - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
                                counter >= 0; counter--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
                                if(insertPath[counter] == ec) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
                                    if(counter != (insertPath.length - 1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
                                        first = ec.parent.getElement(ec.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
                        if(first == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
                            first = ec.parent.getElement(ec.index + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
                        Element leaf = createLeafElement(ec.parent, first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
                                 getAttributes(), pos, first.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
                        ec.added.addElement(leaf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
                        ec.removed.addElement(first);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
                        // Parent was fractured element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
                        Element first = ec.parent.getElement(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
                        Element leaf = createLeafElement(ec.parent, first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
                                 getAttributes(), pos, first.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
                        ec.added.addElement(leaf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
                        ec.removed.addElement(first);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
                pos += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
         * Remove the elements from <code>elem</code> in range
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1923
         * <code>rmOffs0</code>, <code>rmOffs1</code>. This uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
         * <code>canJoin</code> and <code>join</code> to handle joining
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
         * the endpoints of the insertion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1927
         * @return true if elem will no longer have any elements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
        boolean removeElements(Element elem, int rmOffs0, int rmOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
            if (! elem.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
                // update path for changes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
                int index0 = elem.getElementIndex(rmOffs0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
                int index1 = elem.getElementIndex(rmOffs1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
                push(elem, index0);
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  1935
                ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1936
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1937
                // if the range is contained by one element,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1938
                // we just forward the request
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1939
                if (index0 == index1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1940
                    Element child0 = elem.getElement(index0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1941
                    if(rmOffs0 <= child0.getStartOffset() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1942
                       rmOffs1 >= child0.getEndOffset()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1943
                        // Element totally removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1944
                        ec.removed.addElement(child0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1945
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1946
                    else if(removeElements(child0, rmOffs0, rmOffs1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1947
                        ec.removed.addElement(child0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1948
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1949
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1950
                    // the removal range spans elements.  If we can join
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1951
                    // the two endpoints, do it.  Otherwise we remove the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1952
                    // interior and forward to the endpoints.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1953
                    Element child0 = elem.getElement(index0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1954
                    Element child1 = elem.getElement(index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1955
                    boolean containsOffs1 = (rmOffs1 < elem.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1956
                    if (containsOffs1 && canJoin(child0, child1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1957
                        // remove and join
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1958
                        for (int i = index0; i <= index1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1959
                            ec.removed.addElement(elem.getElement(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1960
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1961
                        Element e = join(elem, child0, child1, rmOffs0, rmOffs1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1962
                        ec.added.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1963
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1964
                        // remove interior and forward
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1965
                        int rmIndex0 = index0 + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1966
                        int rmIndex1 = index1 - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1967
                        if (child0.getStartOffset() == rmOffs0 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1968
                            (index0 == 0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1969
                             child0.getStartOffset() > rmOffs0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1970
                             child0.getEndOffset() <= rmOffs1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1971
                            // start element completely consumed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1972
                            child0 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1973
                            rmIndex0 = index0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1974
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1975
                        if (!containsOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1976
                            child1 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1977
                            rmIndex1++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1978
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1979
                        else if (child1.getStartOffset() == rmOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1980
                            // end element not touched
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1981
                            child1 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1982
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1983
                        if (rmIndex0 <= rmIndex1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1984
                            ec.index = rmIndex0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1985
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1986
                        for (int i = rmIndex0; i <= rmIndex1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1987
                            ec.removed.addElement(elem.getElement(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1988
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1989
                        if (child0 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1990
                            if(removeElements(child0, rmOffs0, rmOffs1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1991
                                ec.removed.insertElementAt(child0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1992
                                ec.index = index0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1993
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1994
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1995
                        if (child1 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1996
                            if(removeElements(child1, rmOffs0, rmOffs1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1997
                                ec.removed.addElement(child1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1998
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1999
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2000
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2001
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2002
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2003
                // publish changes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2004
                pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2006
                // Return true if we no longer have any children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2007
                if(elem.getElementCount() == (ec.removed.size() -
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2008
                                              ec.added.size())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2009
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2010
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2011
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2012
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2013
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2014
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2015
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2016
         * Can the two given elements be coelesced together
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2017
         * into one element?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2018
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2019
        boolean canJoin(Element e0, Element e1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2020
            if ((e0 == null) || (e1 == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2021
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2022
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2023
            // Don't join a leaf to a branch.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2024
            boolean leaf0 = e0.isLeaf();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2025
            boolean leaf1 = e1.isLeaf();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2026
            if(leaf0 != leaf1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2027
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2028
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2029
            if (leaf0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2030
                // Only join leaves if the attributes match, otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2031
                // style information will be lost.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2032
                return e0.getAttributes().isEqual(e1.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2033
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2034
            // Only join non-leafs if the names are equal. This may result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2035
            // in loss of style information, but this is typically acceptable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2036
            // for non-leafs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2037
            String name0 = e0.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2038
            String name1 = e1.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2039
            if (name0 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2040
                return name0.equals(name1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2041
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2042
            if (name1 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2043
                return name1.equals(name0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2044
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2045
            // Both names null, treat as equal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2046
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2047
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2048
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2049
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2050
         * Joins the two elements carving out a hole for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2051
         * given removed range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2052
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2053
        Element join(Element p, Element left, Element right, int rmOffs0, int rmOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2054
            if (left.isLeaf() && right.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2055
                return createLeafElement(p, left.getAttributes(), left.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2056
                                         right.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2057
            } else if ((!left.isLeaf()) && (!right.isLeaf())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2058
                // join two branch elements.  This copies the children before
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2059
                // the removal range on the left element, and after the removal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2060
                // range on the right element.  The two elements on the edge
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2061
                // are joined if possible and needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2062
                Element to = createBranchElement(p, left.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2063
                int ljIndex = left.getElementIndex(rmOffs0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2064
                int rjIndex = right.getElementIndex(rmOffs1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2065
                Element lj = left.getElement(ljIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2066
                if (lj.getStartOffset() >= rmOffs0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2067
                    lj = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2068
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2069
                Element rj = right.getElement(rjIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2070
                if (rj.getStartOffset() == rmOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2071
                    rj = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2072
                }
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2073
                Vector<Element> children = new Vector<Element>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2075
                // transfer the left
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2076
                for (int i = 0; i < ljIndex; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2077
                    children.addElement(clone(to, left.getElement(i)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2078
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2079
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2080
                // transfer the join/middle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2081
                if (canJoin(lj, rj)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2082
                    Element e = join(to, lj, rj, rmOffs0, rmOffs1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2083
                    children.addElement(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2084
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2085
                    if (lj != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2086
                        children.addElement(cloneAsNecessary(to, lj, rmOffs0, rmOffs1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2087
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2088
                    if (rj != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2089
                        children.addElement(cloneAsNecessary(to, rj, rmOffs0, rmOffs1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2090
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2091
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2092
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2093
                // transfer the right
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2094
                int n = right.getElementCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2095
                for (int i = (rj == null) ? rjIndex : rjIndex + 1; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2096
                    children.addElement(clone(to, right.getElement(i)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2097
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2098
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2099
                // install the children
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2100
                Element[] c = new Element[children.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2101
                children.copyInto(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2102
                ((BranchElement)to).replace(0, 0, c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2103
                return to;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2104
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2105
                throw new StateInvariantError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2106
                    "No support to join leaf element with non-leaf element");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2107
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2108
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2109
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2110
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2111
         * Creates a copy of this element, with a different
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2112
         * parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2113
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2114
         * @param parent the parent element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2115
         * @param clonee the element to be cloned
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2116
         * @return the copy
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2117
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2118
        public Element clone(Element parent, Element clonee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2119
            if (clonee.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2120
                return createLeafElement(parent, clonee.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2121
                                         clonee.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2122
                                         clonee.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2123
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2124
            Element e = createBranchElement(parent, clonee.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2125
            int n = clonee.getElementCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2126
            Element[] children = new Element[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2127
            for (int i = 0; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2128
                children[i] = clone(e, clonee.getElement(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2129
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2130
            ((BranchElement)e).replace(0, 0, children);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2131
            return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2132
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2133
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2134
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2135
         * Creates a copy of this element, with a different
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2136
         * parent. Children of this element included in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2137
         * removal range will be discarded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2138
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2139
        Element cloneAsNecessary(Element parent, Element clonee, int rmOffs0, int rmOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2140
            if (clonee.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2141
                return createLeafElement(parent, clonee.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2142
                                         clonee.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2143
                                         clonee.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2144
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2145
            Element e = createBranchElement(parent, clonee.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2146
            int n = clonee.getElementCount();
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2147
            ArrayList<Element> childrenList = new ArrayList<Element>(n);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2148
            for (int i = 0; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2149
                Element elem = clonee.getElement(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2150
                if (elem.getStartOffset() < rmOffs0 || elem.getEndOffset() > rmOffs1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2151
                    childrenList.add(cloneAsNecessary(e, elem, rmOffs0, rmOffs1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2152
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2153
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2154
            Element[] children = new Element[childrenList.size()];
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2155
            children = childrenList.toArray(children);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2156
            ((BranchElement)e).replace(0, 0, children);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2157
            return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2158
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2159
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2160
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2161
         * Determines if a fracture needs to be performed. A fracture
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2162
         * can be thought of as moving the right part of a tree to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2163
         * new location, where the right part is determined by what has
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2164
         * been inserted. <code>depth</code> is used to indicate a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2165
         * JoinToFracture is needed to an element at a depth
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2166
         * of <code>depth</code>. Where the root is 0, 1 is the children
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2167
         * of the root...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2168
         * <p>This will invoke <code>fractureFrom</code> if it is determined
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2169
         * a fracture needs to happen.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2170
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2171
        void fracture(int depth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2172
            int cLength = insertPath.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2173
            int lastIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2174
            boolean needRecreate = recreateLeafs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2175
            ElemChanges lastChange = insertPath[cLength - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2176
            // Use childAltered to determine when a child has been altered,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2177
            // that is the point of insertion is less than the element count.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2178
            boolean childAltered = ((lastChange.index + 1) <
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2179
                                    lastChange.parent.getElementCount());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2180
            int deepestAlteredIndex = (needRecreate) ? cLength : -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2181
            int lastAlteredIndex = cLength - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2182
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2183
            createdFracture = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2184
            // Determine where to start recreating from.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2185
            // Start at - 2, as first one is indicated by recreateLeafs and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2186
            // childAltered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2187
            for(int counter = cLength - 2; counter >= 0; counter--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2188
                ElemChanges change = insertPath[counter];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2189
                if(change.added.size() > 0 || counter == depth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2190
                    lastIndex = counter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2191
                    if(!needRecreate && childAltered) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2192
                        needRecreate = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2193
                        if(deepestAlteredIndex == -1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2194
                            deepestAlteredIndex = lastAlteredIndex + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2195
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2196
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2197
                if(!childAltered && change.index <
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2198
                   change.parent.getElementCount()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2199
                    childAltered = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2200
                    lastAlteredIndex = counter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2201
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2202
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2203
            if(needRecreate) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2204
                // Recreate all children to right of parent starting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2205
                // at lastIndex.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2206
                if(lastIndex == -1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2207
                    lastIndex = cLength - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2208
                fractureFrom(insertPath, lastIndex, deepestAlteredIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2209
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2210
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2211
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2212
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2213
         * Recreates the elements to the right of the insertion point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2214
         * This starts at <code>startIndex</code> in <code>changed</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2215
         * and calls duplicate to duplicate existing elements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2216
         * This will also duplicate the elements along the insertion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2217
         * point, until a depth of <code>endFractureIndex</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2218
         * reached, at which point only the elements to the right of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2219
         * the insertion point are duplicated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2220
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2221
        void fractureFrom(ElemChanges[] changed, int startIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2222
                          int endFractureIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2223
            // Recreate the element representing the inserted index.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2224
            ElemChanges change = changed[startIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2225
            Element child;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2226
            Element newChild;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2227
            int changeLength = changed.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2228
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2229
            if((startIndex + 1) == changeLength)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2230
                child = change.parent.getElement(change.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2231
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2232
                child = change.parent.getElement(change.index - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2233
            if(child.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2234
                newChild = createLeafElement(change.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2235
                               child.getAttributes(), Math.max(endOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2236
                               child.getStartOffset()), child.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2237
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2238
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2239
                newChild = createBranchElement(change.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2240
                                               child.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2241
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2242
            fracturedParent = change.parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2243
            fracturedChild = newChild;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2244
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2245
            // Recreate all the elements to the right of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2246
            // insertion point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2247
            Element parent = newChild;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2248
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2249
            while(++startIndex < endFractureIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2250
                boolean isEnd = ((startIndex + 1) == endFractureIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2251
                boolean isEndLeaf = ((startIndex + 1) == changeLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2252
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2253
                // Create the newChild, a duplicate of the elment at
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2254
                // index. This isn't done if isEnd and offsetLastIndex are true
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2255
                // indicating a join previous was done.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2256
                change = changed[startIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2257
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2258
                // Determine the child to duplicate, won't have to duplicate
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2259
                // if at end of fracture, or offseting index.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2260
                if(isEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2261
                    if(offsetLastIndex || !isEndLeaf)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2262
                        child = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2263
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2264
                        child = change.parent.getElement(change.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2265
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2266
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2267
                    child = change.parent.getElement(change.index - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2268
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2269
                // Duplicate it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2270
                if(child != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2271
                    if(child.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2272
                        newChild = createLeafElement(parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2273
                               child.getAttributes(), Math.max(endOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2274
                               child.getStartOffset()), child.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2275
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2276
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2277
                        newChild = createBranchElement(parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2278
                                                   child.getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2279
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2280
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2281
                else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2282
                    newChild = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2283
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2284
                // Recreate the remaining children (there may be none).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2285
                int kidsToMove = change.parent.getElementCount() -
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2286
                                 change.index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2287
                Element[] kids;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2288
                int moveStartIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2289
                int kidStartIndex = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2290
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2291
                if(newChild == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2292
                    // Last part of fracture.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2293
                    if(isEndLeaf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2294
                        kidsToMove--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2295
                        moveStartIndex = change.index + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2296
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2297
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2298
                        moveStartIndex = change.index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2299
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2300
                    kidStartIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2301
                    kids = new Element[kidsToMove];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2302
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2303
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2304
                    if(!isEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2305
                        // Branch.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2306
                        kidsToMove++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2307
                        moveStartIndex = change.index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2308
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2309
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2310
                        // Last leaf, need to recreate part of it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2311
                        moveStartIndex = change.index + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2312
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2313
                    kids = new Element[kidsToMove];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2314
                    kids[0] = newChild;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2315
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2316
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2317
                for(int counter = kidStartIndex; counter < kidsToMove;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2318
                    counter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2319
                    Element toMove =change.parent.getElement(moveStartIndex++);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2320
                    kids[counter] = recreateFracturedElement(parent, toMove);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2321
                    change.removed.addElement(toMove);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2322
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2323
                ((BranchElement)parent).replace(0, 0, kids);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2324
                parent = newChild;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2325
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2327
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2328
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2329
         * Recreates <code>toDuplicate</code>. This is called when an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2330
         * element needs to be created as the result of an insertion. This
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 20458
diff changeset
  2331
         * will recurse and create all the children. This is similar to
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2332
         * <code>clone</code>, but deteremines the offsets differently.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2333
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2334
        Element recreateFracturedElement(Element parent, Element toDuplicate) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2335
            if(toDuplicate.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2336
                return createLeafElement(parent, toDuplicate.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2337
                                         Math.max(toDuplicate.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2338
                                                  endOffset),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2339
                                         toDuplicate.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2340
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2341
            // Not a leaf
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2342
            Element newParent = createBranchElement(parent, toDuplicate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2343
                                                    getAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2344
            int childCount = toDuplicate.getElementCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2345
            Element[] newKids = new Element[childCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2346
            for(int counter = 0; counter < childCount; counter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2347
                newKids[counter] = recreateFracturedElement(newParent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2348
                                             toDuplicate.getElement(counter));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2349
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2350
            ((BranchElement)newParent).replace(0, 0, newKids);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2351
            return newParent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2352
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2353
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2354
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2355
         * Splits the bottommost leaf in <code>path</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2356
         * This is called from insert when the first element is NOT content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2357
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2358
        void fractureDeepestLeaf(ElementSpec[] specs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2359
            // Split the bottommost leaf. It will be recreated elsewhere.
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2360
            ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2361
            Element child = ec.parent.getElement(ec.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2362
            // Inserts at offset 0 do not need to recreate child (it would
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2363
            // have a length of 0!).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2364
            if (offset != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2365
                Element newChild = createLeafElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2366
                                                 child.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2367
                                                 child.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2368
                                                 offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2369
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2370
                ec.added.addElement(newChild);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2371
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2372
            ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2373
            if(child.getEndOffset() != endOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2374
                recreateLeafs = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2375
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2376
                offsetLastIndex = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2377
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2378
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2379
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2380
         * Inserts the first content. This needs to be separate to handle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2381
         * joining.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2382
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2383
        void insertFirstContent(ElementSpec[] specs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2384
            ElementSpec firstSpec = specs[0];
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2385
            ElemChanges ec = path.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2386
            Element child = ec.parent.getElement(ec.index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2387
            int firstEndOffset = offset + firstSpec.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2388
            boolean isOnlyContent = (specs.length == 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2389
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2390
            switch(firstSpec.getDirection()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2391
            case ElementSpec.JoinPreviousDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2392
                if(child.getEndOffset() != firstEndOffset &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2393
                    !isOnlyContent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2394
                    // Create the left split part containing new content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2395
                    Element newE = createLeafElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2396
                            child.getAttributes(), child.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2397
                            firstEndOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2398
                    ec.added.addElement(newE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2399
                    ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2400
                    // Remainder will be created later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2401
                    if(child.getEndOffset() != endOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2402
                        recreateLeafs = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2403
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2404
                        offsetLastIndex = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2405
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2406
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2407
                    offsetLastIndex = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2408
                    offsetLastIndexOnReplace = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2409
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2410
                // else Inserted at end, and is total length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2411
                // Update index incase something added/removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2412
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2413
            case ElementSpec.JoinNextDirection:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2414
                if(offset != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2415
                    // Recreate the first element, its offset will have
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2416
                    // changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2417
                    Element newE = createLeafElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2418
                            child.getAttributes(), child.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2419
                            offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2420
                    ec.added.addElement(newE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2421
                    // Recreate the second, merge part. We do no checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2422
                    // to see if JoinNextDirection is valid here!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2423
                    Element nextChild = ec.parent.getElement(ec.index + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2424
                    if(isOnlyContent)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2425
                        newE = createLeafElement(ec.parent, nextChild.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2426
                            getAttributes(), offset, nextChild.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2427
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2428
                        newE = createLeafElement(ec.parent, nextChild.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2429
                            getAttributes(), offset, firstEndOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2430
                    ec.added.addElement(newE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2431
                    ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2432
                    ec.removed.addElement(nextChild);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2433
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2434
                // else nothin to do.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2435
                // PENDING: if !isOnlyContent could raise here!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2436
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2437
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2438
                // Inserted into middle, need to recreate split left
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2439
                // new content, and split right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2440
                if(child.getStartOffset() != offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2441
                    Element newE = createLeafElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2442
                            child.getAttributes(), child.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2443
                            offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2444
                    ec.added.addElement(newE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2445
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2446
                ec.removed.addElement(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2447
                // new content
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2448
                Element newE = createLeafElement(ec.parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2449
                                                 firstSpec.getAttributes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2450
                                                 offset, firstEndOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2451
                ec.added.addElement(newE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2452
                if(child.getEndOffset() != endOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2453
                    // Signals need to recreate right split later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2454
                    recreateLeafs = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2455
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2456
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2457
                    offsetLastIndex = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2458
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2459
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2460
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2461
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2462
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2463
        Element root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2464
        transient int pos;          // current position
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2465
        transient int offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2466
        transient int length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2467
        transient int endOffset;
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2468
        transient Vector<ElemChanges> changes;
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2469
        transient Stack<ElemChanges> path;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2470
        transient boolean insertOp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2471
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2472
        transient boolean recreateLeafs; // For insert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2473
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2474
        /** For insert, path to inserted elements. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2475
        transient ElemChanges[] insertPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2476
        /** Only for insert, set to true when the fracture has been created. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2477
        transient boolean createdFracture;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2478
        /** Parent that contains the fractured child. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2479
        transient Element fracturedParent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2480
        /** Fractured child. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2481
        transient Element fracturedChild;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2482
        /** Used to indicate when fracturing that the last leaf should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2483
         * skipped. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2484
        transient boolean offsetLastIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2485
        /** Used to indicate that the parent of the deepest leaf should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2486
         * offset the index by 1 when adding/removing elements in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2487
         * insert. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2488
        transient boolean offsetLastIndexOnReplace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2489
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2490
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2491
         * Internal record used to hold element change specifications
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2492
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2493
        class ElemChanges {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2494
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2495
            ElemChanges(Element parent, int index, boolean isFracture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2496
                this.parent = parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2497
                this.index = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2498
                this.isFracture = isFracture;
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2499
                added = new Vector<Element>();
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2500
                removed = new Vector<Element>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2501
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2502
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2503
            public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2504
                return "added: " + added + "\nremoved: " + removed + "\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2505
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2506
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2507
            Element parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2508
            int index;
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2509
            Vector<Element> added;
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2510
            Vector<Element> removed;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2511
            boolean isFracture;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2512
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2513
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2514
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2515
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2516
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2517
     * An UndoableEdit used to remember AttributeSet changes to an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2518
     * Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2519
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2520
    public static class AttributeUndoableEdit extends AbstractUndoableEdit {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2521
        public AttributeUndoableEdit(Element element, AttributeSet newAttributes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2522
                              boolean isReplacing) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2523
            super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2524
            this.element = element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2525
            this.newAttributes = newAttributes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2526
            this.isReplacing = isReplacing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2527
            // If not replacing, it may be more efficient to only copy the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2528
            // changed values...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2529
            copy = element.getAttributes().copyAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2530
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2531
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2532
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2533
         * Redoes a change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2534
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2535
         * @exception CannotRedoException if the change cannot be redone
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2536
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2537
        public void redo() throws CannotRedoException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2538
            super.redo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2539
            MutableAttributeSet as = (MutableAttributeSet)element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2540
                                     .getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2541
            if(isReplacing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2542
                as.removeAttributes(as);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2543
            as.addAttributes(newAttributes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2544
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2545
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2546
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2547
         * Undoes a change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2548
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2549
         * @exception CannotUndoException if the change cannot be undone
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2550
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2551
        public void undo() throws CannotUndoException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2552
            super.undo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2553
            MutableAttributeSet as = (MutableAttributeSet)element.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2554
            as.removeAttributes(as);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2555
            as.addAttributes(copy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2556
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2557
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2558
        // AttributeSet containing additional entries, must be non-mutable!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2559
        protected AttributeSet newAttributes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2560
        // Copy of the AttributeSet the Element contained.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2561
        protected AttributeSet copy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2562
        // true if all the attributes in the element were removed first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2563
        protected boolean isReplacing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2564
        // Efected Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2565
        protected Element element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2566
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2567
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2568
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2569
     * UndoableEdit for changing the resolve parent of an Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2570
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2571
    static class StyleChangeUndoableEdit extends AbstractUndoableEdit {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2572
        public StyleChangeUndoableEdit(AbstractElement element,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2573
                                       Style newStyle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2574
            super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2575
            this.element = element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2576
            this.newStyle = newStyle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2577
            oldStyle = element.getResolveParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2578
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2579
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2580
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2581
         * Redoes a change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2582
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2583
         * @exception CannotRedoException if the change cannot be redone
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2584
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2585
        public void redo() throws CannotRedoException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2586
            super.redo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2587
            element.setResolveParent(newStyle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2589
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2590
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2591
         * Undoes a change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2592
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2593
         * @exception CannotUndoException if the change cannot be undone
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2594
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2595
        public void undo() throws CannotUndoException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2596
            super.undo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2597
            element.setResolveParent(oldStyle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2598
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2599
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2600
        /** Element to change resolve parent of. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2601
        protected AbstractElement element;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2602
        /** New style. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2603
        protected Style newStyle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2604
        /** Old style, before setting newStyle. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2605
        protected AttributeSet oldStyle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2606
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2607
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2608
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2609
     * Base class for style change handlers with support for stale objects detection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2610
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2611
    abstract static class AbstractChangeHandler implements ChangeListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2612
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2613
        /* This has an implicit reference to the handler object.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2614
        private class DocReference extends WeakReference<DefaultStyledDocument> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2615
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2616
            DocReference(DefaultStyledDocument d, ReferenceQueue<DefaultStyledDocument> q) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2617
                super(d, q);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2618
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2619
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2620
            /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2621
             * Return a reference to the style change handler object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2622
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2623
            ChangeListener getListener() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2624
                return AbstractChangeHandler.this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2625
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2626
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2627
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2628
        /** Class-specific reference queues.  */
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2629
        private final static Map<Class, ReferenceQueue<DefaultStyledDocument>> queueMap
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2630
                = new HashMap<Class, ReferenceQueue<DefaultStyledDocument>>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2631
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2632
        /** A weak reference to the document object.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2633
        private DocReference doc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2634
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2635
        AbstractChangeHandler(DefaultStyledDocument d) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2636
            Class c = getClass();
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2637
            ReferenceQueue<DefaultStyledDocument> q;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2638
            synchronized (queueMap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2639
                q = queueMap.get(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2640
                if (q == null) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2641
                    q = new ReferenceQueue<DefaultStyledDocument>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2642
                    queueMap.put(c, q);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2643
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2644
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2645
            doc = new DocReference(d, q);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2646
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2647
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2648
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2649
         * Return a list of stale change listeners.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2650
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2651
         * A change listener becomes "stale" when its document is cleaned by GC.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2652
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2653
        static List<ChangeListener> getStaleListeners(ChangeListener l) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2654
            List<ChangeListener> staleListeners = new ArrayList<ChangeListener>();
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
  2655
            ReferenceQueue<DefaultStyledDocument> q = queueMap.get(l.getClass());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2656
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2657
            if (q != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2658
                DocReference r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2659
                synchronized (q) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2660
                    while ((r = (DocReference) q.poll()) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2661
                        staleListeners.add(r.getListener());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2662
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2663
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2664
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2665
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2666
            return staleListeners;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2667
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2668
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2669
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2670
         * The ChangeListener wrapper which guards against dead documents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2671
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2672
        public void stateChanged(ChangeEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2673
            DefaultStyledDocument d = doc.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2674
            if (d != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2675
                fireStateChanged(d, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2676
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2677
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2678
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2679
        /** Run the actual class-specific stateChanged() method.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2680
        abstract void fireStateChanged(DefaultStyledDocument d, ChangeEvent e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2681
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2682
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2683
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2684
     * Added to all the Styles. When instances of this receive a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2685
     * stateChanged method, styleChanged is invoked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2686
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2687
    static class StyleChangeHandler extends AbstractChangeHandler {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2688
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2689
        StyleChangeHandler(DefaultStyledDocument d) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2690
            super(d);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2691
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2692
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2693
        void fireStateChanged(DefaultStyledDocument d, ChangeEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2694
            Object source = e.getSource();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2695
            if (source instanceof Style) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2696
                d.styleChanged((Style) source);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2697
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2698
                d.styleChanged(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2699
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2700
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2701
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2702
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2703
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2704
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2705
     * Added to the StyleContext. When the StyleContext changes, this invokes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2706
     * <code>updateStylesListeningTo</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2707
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2708
    static class StyleContextChangeHandler extends AbstractChangeHandler {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2709
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2710
        StyleContextChangeHandler(DefaultStyledDocument d) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2711
            super(d);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2712
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2713
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2714
        void fireStateChanged(DefaultStyledDocument d, ChangeEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2715
            d.updateStylesListeningTo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2716
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2717
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2718
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2719
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2720
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2721
     * When run this creates a change event for the complete document
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2722
     * and fires it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2723
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2724
    class ChangeUpdateRunnable implements Runnable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2725
        boolean isPending = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2726
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2727
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2728
            synchronized(this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2729
                isPending = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2730
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2731
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2732
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2733
                writeLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2734
                DefaultDocumentEvent dde = new DefaultDocumentEvent(0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2735
                                              getLength(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2736
                                              DocumentEvent.EventType.CHANGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2737
                dde.end();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2738
                fireChangedUpdate(dde);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2739
            } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2740
                writeUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2741
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2742
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2743
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2744
}