Browse Source

Merge branch 'textpane-fix'

tags/0.6.3m1rc1
Gregory Holmes 15 years ago
parent
commit
3aed5674c2

+ 34
- 48
nbproject/build-impl.xml View File

@@ -19,7 +19,7 @@ is divided into following sections:
19 19
   - cleanup
20 20
 
21 21
         -->
22
-<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject2="http://www.netbeans.org/ns/j2se-project/2" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="DMDirc-impl">
22
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="DMDirc-impl">
23 23
     <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
24 24
     <!-- 
25 25
                 ======================
@@ -102,10 +102,16 @@ is divided into following sections:
102 102
         <property name="javadoc.encoding.used" value="${source.encoding}"/>
103 103
         <property name="includes" value="**"/>
104 104
         <property name="excludes" value=""/>
105
-        <property name="do.depend" value="true"/>
105
+        <property name="do.depend" value="false"/>
106 106
         <condition property="do.depend.true">
107 107
             <istrue value="${do.depend}"/>
108 108
         </condition>
109
+        <condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
110
+            <and>
111
+                <isset property="jaxws.endorsed.dir"/>
112
+                <available file="nbproject/jaxws-build.xml"/>
113
+            </and>
114
+        </condition>
109 115
     </target>
110 116
     <target name="-post-init">
111 117
         <!-- Empty placeholder for easier customization. -->
@@ -140,7 +146,6 @@ is divided into following sections:
140 146
             <attribute default="${includes}" name="includes"/>
141 147
             <attribute default="${excludes}" name="excludes"/>
142 148
             <attribute default="${javac.debug}" name="debug"/>
143
-            <attribute default="" name="javac.compilerargs.jaxws"/>
144 149
             <attribute default="" name="sourcepath"/>
145 150
             <element name="customize" optional="true"/>
146 151
             <sequential>
@@ -148,7 +153,7 @@ is divided into following sections:
148 153
                     <classpath>
149 154
                         <path path="@{classpath}"/>
150 155
                     </classpath>
151
-                    <compilerarg line="${javac.compilerargs} @{javac.compilerargs.jaxws}"/>
156
+                    <compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
152 157
                     <customize/>
153 158
                 </javac>
154 159
             </sequential>
@@ -188,9 +193,6 @@ is divided into following sections:
188 193
             <attribute default="**" name="testincludes"/>
189 194
             <sequential>
190 195
                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
191
-                    <classpath>
192
-                        <pathelement path="${clover.jar}"/>
193
-                    </classpath>
194 196
                     <batchtest todir="${build.test.results.dir}">
195 197
                         <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
196 198
                             <filename name="@{testincludes}"/>
@@ -210,13 +212,13 @@ is divided into following sections:
210 212
             </sequential>
211 213
         </macrodef>
212 214
     </target>
213
-    <target name="-init-macrodef-nbjpda">
215
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
214 216
         <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
215 217
             <attribute default="${main.class}" name="name"/>
216 218
             <attribute default="${debug.classpath}" name="classpath"/>
217 219
             <attribute default="" name="stopclassname"/>
218 220
             <sequential>
219
-                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="dt_socket">
221
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
220 222
                     <classpath>
221 223
                         <path path="@{classpath}"/>
222 224
                     </classpath>
@@ -227,7 +229,9 @@ is divided into following sections:
227 229
             <attribute default="${build.classes.dir}" name="dir"/>
228 230
             <sequential>
229 231
                 <nbjpdareload>
230
-                    <fileset dir="@{dir}" includes="${fix.includes}*.class"/>
232
+                    <fileset dir="@{dir}" includes="${fix.classes}">
233
+                        <include name="${fix.includes}*.class"/>
234
+                    </fileset>
231 235
                 </nbjpdareload>
232 236
             </sequential>
233 237
         </macrodef>
@@ -245,6 +249,12 @@ is divided into following sections:
245 249
         <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
246 250
             <istrue value="${have-jdk-older-than-1.4}"/>
247 251
         </condition>
252
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
253
+            <os family="windows"/>
254
+        </condition>
255
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
256
+            <isset property="debug.transport"/>
257
+        </condition>
248 258
     </target>
249 259
     <target depends="-init-debug-args" name="-init-macrodef-debug">
250 260
         <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
@@ -254,7 +264,7 @@ is divided into following sections:
254 264
             <sequential>
255 265
                 <java classname="@{classname}" dir="${work.dir}" fork="true">
256 266
                     <jvmarg line="${debug-args-line}"/>
257
-                    <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
267
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
258 268
                     <jvmarg line="${run.jvmargs}"/>
259 269
                     <classpath>
260 270
                         <path path="@{classpath}"/>
@@ -290,7 +300,7 @@ is divided into following sections:
290 300
     <target name="-init-presetdef-jar">
291 301
         <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
292 302
             <jar compress="${jar.compress}" jarfile="${dist.jar}">
293
-                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.jar.excludes}"/>
303
+                <j2seproject1:fileset dir="${build.classes.dir}"/>
294 304
             </jar>
295 305
         </presetdef>
296 306
     </target>
@@ -301,6 +311,13 @@ is divided into following sections:
301 311
                 ===================
302 312
             -->
303 313
     <target depends="init" name="deps-jar" unless="no.deps"/>
314
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
315
+    <target depends="init" name="-check-automatic-build">
316
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
317
+    </target>
318
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
319
+        <antcall target="clean"/>
320
+    </target>
304 321
     <target depends="init,deps-jar" name="-pre-pre-compile">
305 322
         <mkdir dir="${build.classes.dir}"/>
306 323
     </target>
@@ -321,7 +338,7 @@ is divided into following sections:
321 338
         <!-- Empty placeholder for easier customization. -->
322 339
         <!-- You can override this target in the ../build.xml file. -->
323 340
     </target>
324
-    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
341
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
325 342
     <target name="-pre-compile-single">
326 343
         <!-- Empty placeholder for easier customization. -->
327 344
         <!-- You can override this target in the ../build.xml file. -->
@@ -335,7 +352,7 @@ is divided into following sections:
335 352
         <!-- Empty placeholder for easier customization. -->
336 353
         <!-- You can override this target in the ../build.xml file. -->
337 354
     </target>
338
-    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
355
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
339 356
     <!--
340 357
                 ====================
341 358
                 JAR BUILDING SECTION
@@ -385,7 +402,7 @@ is divided into following sections:
385 402
         </pathconvert>
386 403
         <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
387 404
         <copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
388
-            <fileset dir="${build.classes.dir}" excludes="${dist.jar.excludes}" />
405
+            <fileset dir="${build.classes.dir}"/>
389 406
             <manifest>
390 407
                 <attribute name="Main-Class" value="${main.class}"/>
391 408
                 <attribute name="Class-Path" value="${jar.classpath}"/>
@@ -459,7 +476,7 @@ is divided into following sections:
459 476
             -->
460 477
     <target depends="init" name="-javadoc-build">
461 478
         <mkdir dir="${dist.javadoc.dir}"/>
462
-        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="${javadoc.encoding.used}" destdir="${dist.javadoc.dir}" docencoding="${javadoc.encoding.used}" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
479
+        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
463 480
             <classpath>
464 481
                 <path path="${javac.classpath}"/>
465 482
             </classpath>
@@ -468,41 +485,10 @@ is divided into following sections:
468 485
             </fileset>
469 486
         </javadoc>
470 487
     </target>
471
-
472
-    <target name="move-javadoc-check">
473
-        <condition property="move.javadoc">
474
-            <isset property="javadoc.moveto"/>
475
-        </condition>
476
-    </target>
477
-    <target name="move-javadoc" depends="move-javadoc-check" if="move.javadoc">
478
-        <delete dir="${javadoc.moveto}"/>
479
-        <move file="${dist.javadoc.dir}" tofile="${javadoc.moveto}"/>
480
-    </target>
481
-
482
-    <target depends="init,-doccheck-check" name="-doccheck-build" if="doccheck.run">
483
-        <mkdir dir="${doccheck.dir}"/>
484
-        <javadoc additionalparam="-doclet com.sun.tools.doclets.doccheck.DocCheck -docletpath ${doccheck.path} -skipPkg net.miginfocom.*" author="${javadoc.author}" destdir="${doccheck.dir}" failonerror="true" private="${javadoc.private}" source="${javac.source}" sourcepath="${src.dir}" useexternalfile="true" version="${javadoc.version}">
485
-            <classpath>
486
-                <path path="${javac.classpath}"/>
487
-            </classpath>
488
-        </javadoc>
489
-    </target>
490
-
491
-    <target name="-doccheck-check">
492
-        <condition property="doccheck.run">
493
-            <and>
494
-                <isset property="doccheck.path"/>
495
-                <isset property="doccheck.dir"/>
496
-                <available file="${doccheck.path}"/>
497
-            </and>
498
-        </condition>
499
-    </target>
500
-
501 488
     <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
502 489
         <nbbrowse file="${dist.javadoc.dir}/index.html"/>
503 490
     </target>
504
-    <target depends="init,-javadoc-build,-javadoc-browse,move-javadoc,-doccheck-build" description="Build Javadoc." name="javadoc"/>
505
-    <target depends="-doccheck-build" description="Build Javadoc error report (doccheck)." name="doccheck"/>
491
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
506 492
     <!--
507 493
                 =========================
508 494
                 JUNIT COMPILATION SECTION

+ 2
- 2
nbproject/genfiles.properties View File

@@ -10,5 +10,5 @@ nbproject/profiler-build-impl.xml.data.CRC32=bd5a0d51
10 10
 nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
11 11
 nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf
12 12
 nbproject/build-impl.xml.data.CRC32=bd5a0d51
13
-nbproject/build-impl.xml.script.CRC32=c389cfac
14
-nbproject/build-impl.xml.stylesheet.CRC32=487672f9
13
+nbproject/build-impl.xml.script.CRC32=a83a4152
14
+nbproject/build-impl.xml.stylesheet.CRC32=e55b27f5

+ 6
- 6
src/com/dmdirc/addons/ui_swing/ChannelFrame.java View File

@@ -24,17 +24,17 @@ package com.dmdirc.addons.ui_swing;
24 24
 
25 25
 import com.dmdirc.Channel;
26 26
 import com.dmdirc.ServerState;
27
-import com.dmdirc.commandparser.PopupType;
28
-import com.dmdirc.commandparser.parsers.ChannelCommandParser;
29
-import com.dmdirc.commandparser.parsers.CommandParser;
30
-import com.dmdirc.parser.irc.ChannelClientInfo;
31
-import com.dmdirc.ui.interfaces.ChannelWindow;
32 27
 import com.dmdirc.addons.ui_swing.components.InputTextFrame;
33 28
 import com.dmdirc.addons.ui_swing.components.SnappingJSplitPane;
34 29
 import com.dmdirc.addons.ui_swing.components.SwingInputHandler;
35 30
 import com.dmdirc.addons.ui_swing.components.renderers.NicklistRenderer;
36 31
 import com.dmdirc.addons.ui_swing.dialogs.channelsetting.ChannelSettingsDialog;
37
-import com.dmdirc.addons.ui_swing.textpane.TextPane.ClickType;
32
+import com.dmdirc.addons.ui_swing.textpane.ClickType;
33
+import com.dmdirc.commandparser.PopupType;
34
+import com.dmdirc.commandparser.parsers.ChannelCommandParser;
35
+import com.dmdirc.commandparser.parsers.CommandParser;
36
+import com.dmdirc.parser.irc.ChannelClientInfo;
37
+import com.dmdirc.ui.interfaces.ChannelWindow;
38 38
 
39 39
 import java.awt.Color;
40 40
 import java.awt.Dimension;

+ 17
- 20
src/com/dmdirc/addons/ui_swing/components/TextFrame.java View File

@@ -26,6 +26,15 @@ import com.dmdirc.FrameContainer;
26 26
 import com.dmdirc.Main;
27 27
 import com.dmdirc.actions.ActionManager;
28 28
 import com.dmdirc.actions.CoreActionType;
29
+import com.dmdirc.addons.ui_swing.SwingController;
30
+import com.dmdirc.addons.ui_swing.UIUtilities;
31
+import com.dmdirc.addons.ui_swing.actions.ChannelCopyAction;
32
+import com.dmdirc.addons.ui_swing.actions.CommandAction;
33
+import com.dmdirc.addons.ui_swing.actions.HyperlinkCopyAction;
34
+import com.dmdirc.addons.ui_swing.actions.NicknameCopyAction;
35
+import com.dmdirc.addons.ui_swing.actions.SearchAction;
36
+import com.dmdirc.addons.ui_swing.actions.TextPaneCopyAction;
37
+import com.dmdirc.addons.ui_swing.textpane.ClickType;
29 38
 import com.dmdirc.commandparser.PopupManager;
30 39
 import com.dmdirc.commandparser.PopupMenu;
31 40
 import com.dmdirc.commandparser.PopupMenuItem;
@@ -41,22 +50,13 @@ import com.dmdirc.ui.WindowManager;
41 50
 import com.dmdirc.ui.interfaces.InputWindow;
42 51
 import com.dmdirc.ui.interfaces.Window;
43 52
 import com.dmdirc.ui.messages.Formatter;
44
-import com.dmdirc.ui.messages.Styliser;
45
-import com.dmdirc.addons.ui_swing.SwingController;
46
-import com.dmdirc.addons.ui_swing.actions.ChannelCopyAction;
47
-import com.dmdirc.addons.ui_swing.actions.CommandAction;
48
-import com.dmdirc.addons.ui_swing.actions.HyperlinkCopyAction;
49
-import com.dmdirc.addons.ui_swing.actions.NicknameCopyAction;
50
-import com.dmdirc.addons.ui_swing.actions.SearchAction;
51
-import com.dmdirc.addons.ui_swing.actions.TextPaneCopyAction;
53
+import com.dmdirc.addons.ui_swing.textpane.Line;
52 54
 import com.dmdirc.addons.ui_swing.textpane.LineInfo;
53 55
 import com.dmdirc.addons.ui_swing.textpane.TextPane;
54
-import com.dmdirc.addons.ui_swing.textpane.TextPane.ClickType;
55
-import com.dmdirc.addons.ui_swing.textpane.TextPanePageUpAction;
56 56
 import com.dmdirc.addons.ui_swing.textpane.TextPanePageDownAction;
57
-import com.dmdirc.addons.ui_swing.UIUtilities;
58
-
57
+import com.dmdirc.addons.ui_swing.textpane.TextPanePageUpAction;
59 58
 import com.dmdirc.util.URLHandler;
59
+
60 60
 import java.awt.Color;
61 61
 import java.awt.Dimension;
62 62
 import java.awt.Point;
@@ -72,7 +72,6 @@ import java.lang.reflect.InvocationTargetException;
72 72
 import java.nio.charset.Charset;
73 73
 import java.nio.charset.IllegalCharsetNameException;
74 74
 import java.nio.charset.UnsupportedCharsetException;
75
-import java.text.AttributedString;
76 75
 import java.util.Date;
77 76
 
78 77
 import java.util.LinkedList;
@@ -239,24 +238,22 @@ public abstract class TextFrame extends JInternalFrame implements Window,
239 238
             /** {@inheritDoc} */
240 239
             @Override
241 240
             public void run() {
242
-                final List<AttributedString> lines = new LinkedList<AttributedString>();
241
+                final List<Line> lines = new LinkedList<Line>();
243 242
                 for (String myLine : encodedLine.split("\n")) {
244 243
                     if (timestamp) {
245
-                        lines.add(TextPane.styledDocumentToAttributedString(
246
-                                Styliser.getStyledString(new String[]{
244
+                        lines.add(new Line(new String[]{
247 245
                             Formatter.formatMessage(getConfigManager(),
248 246
                             "timestamp", new Date()), myLine,
249
-                        })));
247
+                        }));
250 248
                     } else {
251
-                        lines.add(TextPane.styledDocumentToAttributedString(
252
-                                Styliser.getStyledString(new String[]{myLine,})));
249
+                        lines.add(new Line(new String[]{myLine,}));
253 250
                     }
254 251
 
255 252
                     ActionManager.processEvent(CoreActionType.CLIENT_LINE_ADDED,
256 253
                             null, getContainer(), myLine);
257 254
                 }
258 255
                 
259
-                textPane.addText(lines);
256
+                textPane.getDocument().addText(lines);
260 257
 
261 258
                 if (frameBufferSize > 0) {
262 259
                     textPane.trim(frameBufferSize);

+ 14
- 0
src/com/dmdirc/addons/ui_swing/textpane/ClickType.java View File

@@ -0,0 +1,14 @@
1
+
2
+package com.dmdirc.addons.ui_swing.textpane;
3
+
4
+/**
5
+ * Click types.
6
+ */
7
+public enum ClickType {
8
+
9
+    /** Hyperlink. */
10
+    HYPERLINK, /** Channel. */
11
+    CHANNEL, /** Nickname. */
12
+    NICKNAME, /** Normal. */
13
+    NORMAL
14
+}

+ 87
- 92
src/com/dmdirc/addons/ui_swing/textpane/IRCDocument.java View File

@@ -22,46 +22,54 @@
22 22
 
23 23
 package com.dmdirc.addons.ui_swing.textpane;
24 24
 
25
+import com.dmdirc.util.RollingList;
26
+
25 27
 import java.io.Serializable;
26 28
 import java.text.AttributedCharacterIterator;
27 29
 import java.text.AttributedString;
28 30
 import java.util.ArrayList;
29 31
 import java.util.List;
32
+
30 33
 import javax.swing.event.EventListenerList;
31 34
 
32 35
 /**
33 36
  * Data contained in a TextPane.
34 37
  */
35 38
 public final class IRCDocument implements Serializable {
36
-    
39
+
37 40
     /**
38 41
      * A version number for this class. It should be changed whenever the class
39 42
      * structure is changed (or anything else that would prevent serialized
40 43
      * objects being unserialized with the new class).
41 44
      */
42 45
     private static final long serialVersionUID = 4;
43
-    
44
-    /** List of stylised lines of text. */
45
-    private final List<AttributedString> iterators;
46
-    
46
+    /** List of lines of text. */
47
+    private final List<Line> lines;
47 48
     /** Listener list. */
48 49
     private final EventListenerList listeners;
49
-    
50
+    /** Cached lines. */
51
+    private RollingList<Line> cachedLines;
52
+    /** Cached attributed strings. */
53
+    private RollingList<AttributedString> cachedStrings;
54
+
50 55
     /** Creates a new instance of IRCDocument. */
51 56
     public IRCDocument() {
52
-        iterators = new ArrayList<AttributedString>();
57
+        lines = new ArrayList<Line>();
53 58
         listeners = new EventListenerList();
59
+
60
+        cachedLines = new RollingList<Line>(50);
61
+        cachedStrings = new RollingList<AttributedString>(50);
54 62
     }
55
-    
63
+
56 64
     /**
57 65
      * Returns the number of lines in this document.
58 66
      *
59 67
      * @return Number of lines
60 68
      */
61 69
     public int getNumLines() {
62
-        return iterators.size();
70
+        return lines.size();
63 71
     }
64
-    
72
+
65 73
     /**
66 74
      * Returns the Line at the specified number.
67 75
      *
@@ -69,112 +77,59 @@ public final class IRCDocument implements Serializable {
69 77
      *
70 78
      * @return Line at the specified number or null
71 79
      */
72
-    public AttributedString getLine(final int lineNumber) {
73
-        return iterators.get(lineNumber);
80
+    public Line getLine(final int lineNumber) {
81
+        return lines.get(lineNumber);
74 82
     }
75
-    
76
-    /**
77
-     * Returns the range of text from the specified iterator.
78
-     *
79
-     * @param lineNumber line to get text from
80
-     *
81
-     * @return Text in the range from the line
82
-     */
83
-    public String getLineText(final int lineNumber) {
84
-        final AttributedCharacterIterator iterator = getLine(lineNumber).getIterator();
85
-        return getLineText(iterator, iterator.getBeginIndex(), iterator.getEndIndex());
86
-    }
87
-    
88
-    /**
89
-     * Returns the range of text from the specified iterator.
90
-     *
91
-     * @param lineNumber line to get text from
92
-     * @param start Start index in the iterator
93
-     * @param end End index in the iterator
94
-     *
95
-     * @return Text in the range from the line
96
-     */
97
-    public String getLineText(final int lineNumber, final int start, final int end) {
98
-        return getLineText(getLine(lineNumber).getIterator(), start, end);
99
-    }
100
-    
101
-    /**
102
-     * Returns the range of text from the specified iterator.
103
-     *
104
-     * @param iterator iterator to get text from
105
-     * @param start Start index in the iterator
106
-     * @param end End index in the iterator
107
-     *
108
-     * @return Text in the range from the line
109
-     */
110
-    public String getLineText(final AttributedCharacterIterator iterator, final int start, final int end) {
111
-        final StringBuffer text = new StringBuffer();
112
-        for (iterator.setIndex(start); iterator.getIndex() < end; iterator.next()) {
113
-            text.append(iterator.current());
114
-        }
115
-        return text.toString();
116
-    }
117
-    
118
-    /**
119
-     * Returns the length of the specified line
120
-     * 
121
-     * @param lineNumber Line to query
122
-     * 
123
-     * @return Length of the line
124
-     */
125
-    public int getLineLength(final int lineNumber) {
126
-        return iterators.get(lineNumber).getIterator().getEndIndex();
127
-    }    
128
-    
83
+
129 84
     /**
130 85
      * Adds the stylised string to the canvas.
131 86
      * 
132 87
      * @param text stylised string to add to the text
133 88
      */
134
-    public void addText(final AttributedString text) {
135
-        synchronized (iterators) {
136
-            iterators.add(text);
137
-            fireLineAdded(iterators.indexOf(text));
89
+    public void addText(final Line text) {
90
+        synchronized (lines) {
91
+            lines.add(text);
92
+            fireLineAdded(lines.indexOf(text));
138 93
         }
139 94
     }
140
-    
95
+
141 96
     /**
142 97
      * Adds the stylised string to the canvas.
143 98
      * 
144 99
      * @param text stylised string to add to the text
145 100
      */
146
-    public void addText(final List<AttributedString> text) {
147
-        synchronized (iterators) {
148
-            final int start = iterators.size();
149
-            for (AttributedString string : text) {
150
-                iterators.add(string);
101
+    public void addText(final List<Line> text) {
102
+        synchronized (lines) {
103
+            final int start = lines.size();
104
+            for (Line string : text) {
105
+                lines.add(string);
151 106
             }
152 107
             fireLinesAdded(start, text.size());
153 108
         }
154 109
     }
155
-    
110
+
156 111
     /**
157 112
      * Trims the document to the specified number of lines.
158 113
      *
159 114
      * @param numLines Number of lines to trim the document to
160 115
      */
161 116
     public void trim(final int numLines) {
162
-        synchronized (iterators) {
163
-            while (iterators.size() > numLines) {
164
-                iterators.remove(0);
117
+        synchronized (lines) {
118
+            while (lines.size() > numLines) {
119
+                lines.remove(0);
165 120
             }
166 121
             fireTrimmed();
167 122
         }
168 123
     }
169
-    
124
+
170 125
     /** Clears all lines from the document. */
171 126
     protected void clear() {
172
-        synchronized (iterators) {
173
-            iterators.clear();
127
+        synchronized (lines) {
128
+            lines.clear();
174 129
             fireCleared();
175 130
         }
176 131
     }
177
-    
132
+
178 133
     /**
179 134
      * Adds a IRCDocumentListener to the listener list.
180 135
      *
@@ -188,7 +143,7 @@ public final class IRCDocument implements Serializable {
188 143
             listeners.add(IRCDocumentListener.class, listener);
189 144
         }
190 145
     }
191
-    
146
+
192 147
     /**
193 148
      * Removes a IRCDocumentListener from the listener list.
194 149
      *
@@ -197,7 +152,7 @@ public final class IRCDocument implements Serializable {
197 152
     public void removeIRCDocumentListener(final IRCDocumentListener listener) {
198 153
         listeners.remove(IRCDocumentListener.class, listener);
199 154
     }
200
-    
155
+
201 156
     /**
202 157
      * Fires the line added method on all listeners.
203 158
      *
@@ -207,11 +162,12 @@ public final class IRCDocument implements Serializable {
207 162
         final Object[] listenerList = listeners.getListenerList();
208 163
         for (int i = 0; i < listenerList.length; i += 2) {
209 164
             if (listenerList[i] == IRCDocumentListener.class) {
210
-                ((IRCDocumentListener) listenerList[i + 1]).lineAdded(index, iterators.size());
165
+                ((IRCDocumentListener) listenerList[i + 1]).lineAdded(index,
166
+                                                                      lines.size());
211 167
             }
212 168
         }
213 169
     }
214
-    
170
+
215 171
     /**
216 172
      * Fires the lines added method on all listeners.
217 173
      *
@@ -222,11 +178,14 @@ public final class IRCDocument implements Serializable {
222 178
         final Object[] listenerList = listeners.getListenerList();
223 179
         for (int i = 0; i < listenerList.length; i += 2) {
224 180
             if (listenerList[i] == IRCDocumentListener.class) {
225
-                ((IRCDocumentListener) listenerList[i + 1]).linesAdded(index, size, iterators.size());
181
+                ((IRCDocumentListener) listenerList[i + 1]).linesAdded(index,
182
+                                                                       size,
183
+                                                                       lines.
184
+                        size());
226 185
             }
227 186
         }
228 187
     }
229
-    
188
+
230 189
     /**
231 190
      * Fires the trimmed method on all listeners.
232 191
      */
@@ -234,11 +193,11 @@ public final class IRCDocument implements Serializable {
234 193
         final Object[] listenerList = listeners.getListenerList();
235 194
         for (int i = 0; i < listenerList.length; i += 2) {
236 195
             if (listenerList[i] == IRCDocumentListener.class) {
237
-                ((IRCDocumentListener) listenerList[i + 1]).trimmed(iterators.size());
196
+                ((IRCDocumentListener) listenerList[i + 1]).trimmed(lines.size());
238 197
             }
239 198
         }
240 199
     }
241
-    
200
+
242 201
     /**
243 202
      * fires the cleared method on all listeners.
244 203
      */
@@ -250,5 +209,41 @@ public final class IRCDocument implements Serializable {
250 209
             }
251 210
         }
252 211
     }
212
+
213
+    /**
214
+     * Returns an attributed character iterator for a particular line,
215
+     * utilising the document cache where possible.
216
+     *
217
+     * @param line Line to be styled
218
+     *
219
+     * @return Styled line
220
+     */
221
+    public AttributedCharacterIterator getStyledLine(final Line line) {
222
+        AttributedString styledLine = null;
223
+        if (cachedLines.contains(line)) {
224
+            final int index = cachedLines.getList().indexOf(line);
225
+            styledLine = cachedStrings.get(index);
226
+        }
227
+
228
+        if (styledLine == null) {
229
+            styledLine = line.getStyled();
230
+            cachedLines.add(line);
231
+            cachedStrings.add(styledLine);
232
+        }
233
+
234
+        return styledLine.getIterator();
235
+    }
236
+
237
+    /**
238
+     * Returns an attributed string for a particular line, utilising the
239
+     * document cache where possible.
240
+     *
241
+     * @param line Line number to be styled
242
+     *
243
+     * @return Styled line
244
+     */
245
+    public AttributedCharacterIterator getStyledLine(final int line) {
246
+        return getStyledLine(getLine(line));
247
+    }
253 248
 }
254 249
 

+ 3
- 3
src/com/dmdirc/addons/ui_swing/textpane/IRCDocumentSearcher.java View File

@@ -66,7 +66,7 @@ public class IRCDocumentSearcher {
66 66
      */
67 67
     private LinePosition getEndPosition() {
68 68
         final int documentSize = document.getNumLines() - 1;
69
-        final int lineLength = document.getLineLength(documentSize);
69
+        final int lineLength = document.getLine(documentSize).getLength();
70 70
 
71 71
         return new LinePosition(documentSize, lineLength, documentSize,
72 72
                 lineLength);
@@ -93,7 +93,7 @@ public class IRCDocumentSearcher {
93 93
         
94 94
         int line = position.getEndLine();        
95 95
         for (int remaining = document.getNumLines(); remaining > 0; remaining--) {
96
-            final String lineText = document.getLineText(line);
96
+            final String lineText = document.getLine(line).getText();
97 97
             
98 98
             final List<LinePosition> matches = searchLine(line, lineText);
99 99
             
@@ -126,7 +126,7 @@ public class IRCDocumentSearcher {
126 126
         
127 127
         int line = position.getStartLine();        
128 128
         for (int remaining = document.getNumLines(); remaining > 0; remaining--) {
129
-            final String lineText = document.getLineText(line);
129
+            final String lineText = document.getLine(line).getText();
130 130
                         
131 131
             final List<LinePosition> matches = searchLine(line, lineText);
132 132
             

+ 228
- 0
src/com/dmdirc/addons/ui_swing/textpane/Line.java View File

@@ -0,0 +1,228 @@
1
+/*
2
+ * Copyright (c) 2006-2008 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_swing.textpane;
24
+
25
+import com.dmdirc.logger.ErrorLevel;
26
+import com.dmdirc.logger.Logger;
27
+import com.dmdirc.ui.messages.IRCTextAttribute;
28
+import com.dmdirc.ui.messages.Styliser;
29
+
30
+import java.awt.font.TextAttribute;
31
+import java.text.AttributedString;
32
+import java.util.Arrays;
33
+import java.util.Enumeration;
34
+
35
+import javax.swing.UIManager;
36
+import javax.swing.text.AttributeSet;
37
+import javax.swing.text.BadLocationException;
38
+import javax.swing.text.Element;
39
+import javax.swing.text.StyleConstants.CharacterConstants;
40
+import javax.swing.text.StyleConstants.ColorConstants;
41
+import javax.swing.text.StyleConstants.FontConstants;
42
+import javax.swing.text.StyledDocument;
43
+
44
+/**
45
+ * Represents a line of text in IRC.
46
+ */
47
+public class Line {
48
+
49
+    private final String[] lineParts;
50
+
51
+    /**
52
+     * Creates a new line.
53
+     * @param lineParts Parts of the line
54
+     */
55
+    public Line(final String[] lineParts) {
56
+        this.lineParts = lineParts;
57
+    }
58
+
59
+    /**
60
+     * Returns the line parts of this line.
61
+     *
62
+     * @return Lines parts
63
+     */
64
+    public String[] getLineParts() {
65
+        return lineParts;
66
+    }
67
+
68
+    /**
69
+     * Returns the length of the specified line
70
+     * 
71
+     * @return Length of the line
72
+     */
73
+    public int getLength() {
74
+        int length = 0;
75
+        for (String linePart : lineParts) {
76
+            length += linePart.length();
77
+        }
78
+        return length;
79
+    }
80
+
81
+    /**
82
+     * Returns the Line text at the specified number.
83
+     *
84
+     * @return Line at the specified number or null
85
+     */
86
+    public String getText() {
87
+        StringBuilder lineText = new StringBuilder();
88
+        for (String linePart : lineParts) {
89
+            lineText.append(linePart);
90
+        }
91
+        return lineText.toString();
92
+    }
93
+
94
+    /**
95
+     * Converts a StyledDocument into an AttributedString.
96
+     *
97
+     * @return AttributedString representing the specified StyledDocument
98
+     */
99
+    public AttributedString getStyled() {
100
+        final StyledDocument doc = Styliser.getStyledString(lineParts);
101
+
102
+        AttributedString attString = null;
103
+        final Element line = doc.getParagraphElement(0);
104
+        try {
105
+            attString = new AttributedString(line.getDocument().getText(0,
106
+                                                                        line.
107
+                    getDocument().getLength()));
108
+        }
109
+        catch (BadLocationException ex) {
110
+            Logger.userError(ErrorLevel.MEDIUM,
111
+                             "Unable to insert styled string: " +
112
+                             ex.getMessage());
113
+        }
114
+
115
+        if (attString.getIterator().getEndIndex() != 0) {
116
+            attString.addAttribute(TextAttribute.SIZE,
117
+                                   UIManager.getFont("TextPane.font").getSize());
118
+            attString.addAttribute(TextAttribute.FAMILY,
119
+                                   UIManager.getFont("TextPane.font").getFamily());
120
+        }
121
+
122
+        for (int i = 0; i < line.getElementCount(); i++) {
123
+            final Element element = line.getElement(i);
124
+
125
+            final AttributeSet as = element.getAttributes();
126
+            final Enumeration<?> ae = as.getAttributeNames();
127
+
128
+            while (ae.hasMoreElements()) {
129
+                final Object attrib = ae.nextElement();
130
+
131
+                if (attrib == IRCTextAttribute.HYPERLINK) {
132
+                    //Hyperlink
133
+                    attString.addAttribute(IRCTextAttribute.HYPERLINK,
134
+                                           as.getAttribute(attrib), element.
135
+                            getStartOffset(),
136
+                                           element.getEndOffset());
137
+                }
138
+                else if (attrib == IRCTextAttribute.NICKNAME) {
139
+                    //Nicknames
140
+                    attString.addAttribute(IRCTextAttribute.NICKNAME,
141
+                                           as.getAttribute(attrib), element.
142
+                            getStartOffset(),
143
+                                           element.getEndOffset());
144
+                }
145
+                else if (attrib == IRCTextAttribute.CHANNEL) {
146
+                    //Channels
147
+                    attString.addAttribute(IRCTextAttribute.CHANNEL,
148
+                                           as.getAttribute(attrib), element.
149
+                            getStartOffset(),
150
+                                           element.getEndOffset());
151
+                }
152
+                else if (attrib == ColorConstants.Foreground) {
153
+                    //Foreground
154
+                    attString.addAttribute(TextAttribute.FOREGROUND,
155
+                                           as.getAttribute(attrib), element.
156
+                            getStartOffset(),
157
+                                           element.getEndOffset());
158
+                }
159
+                else if (attrib == ColorConstants.Background) {
160
+                    //Background
161
+                    attString.addAttribute(TextAttribute.BACKGROUND,
162
+                                           as.getAttribute(attrib), element.
163
+                            getStartOffset(),
164
+                                           element.getEndOffset());
165
+                }
166
+                else if (attrib == FontConstants.Bold) {
167
+                    //Bold
168
+                    attString.addAttribute(TextAttribute.WEIGHT,
169
+                                           TextAttribute.WEIGHT_BOLD, element.
170
+                            getStartOffset(),
171
+                                           element.getEndOffset());
172
+                }
173
+                else if (attrib == FontConstants.Family) {
174
+                    //Family
175
+                    attString.addAttribute(TextAttribute.FAMILY,
176
+                                           as.getAttribute(attrib), element.
177
+                            getStartOffset(),
178
+                                           element.getEndOffset());
179
+                }
180
+                else if (attrib == FontConstants.Italic) {
181
+                    //italics
182
+                    attString.addAttribute(TextAttribute.POSTURE,
183
+                                           TextAttribute.POSTURE_OBLIQUE,
184
+                                           element.getStartOffset(),
185
+                                           element.getEndOffset());
186
+                }
187
+                else if (attrib == CharacterConstants.Underline) {
188
+                    //Underline
189
+                    attString.addAttribute(TextAttribute.UNDERLINE,
190
+                                           TextAttribute.UNDERLINE_ON, element.
191
+                            getStartOffset(),
192
+                                           element.getEndOffset());
193
+                }
194
+                else if (attrib == IRCTextAttribute.SMILEY) {
195
+                    /* Lets avoid showing broken smileys shall we!
196
+                    final Image image = IconManager.getIconManager().getImage((String) as.getAttribute(attrib)).
197
+                    getScaledInstance(14, 14, Image.SCALE_DEFAULT);
198
+                    ImageGraphicAttribute iga = new ImageGraphicAttribute(image, 
199
+                    (int) BOTTOM_ALIGNMENT, 5, 5);
200
+                    attString.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga,
201
+                    element.getStartOffset(), element.getEndOffset());
202
+                     */
203
+                }
204
+            }
205
+        }
206
+
207
+        if (attString.getIterator().getEndIndex() == 0) {
208
+            return new AttributedString("\n");
209
+        }
210
+
211
+        return attString;
212
+    }
213
+
214
+    /** {@inheritDoc} */
215
+    @Override
216
+    public boolean equals(Object obj) {
217
+        if (obj instanceof Line) {
218
+            return Arrays.equals(((Line) obj).getLineParts(), getLineParts());
219
+        }
220
+        return false;
221
+    }
222
+
223
+    /** {@inheritDoc} */
224
+    @Override
225
+    public int hashCode() {
226
+        return getLineParts().hashCode();
227
+    }
228
+}

+ 1
- 1
src/com/dmdirc/addons/ui_swing/textpane/LineInfo.java View File

@@ -23,7 +23,7 @@
23 23
 package com.dmdirc.addons.ui_swing.textpane;
24 24
 
25 25
 /**
26
- *
26
+ * Information about a position in a line.
27 27
  */
28 28
 public final class LineInfo {
29 29
 

+ 12
- 0
src/com/dmdirc/addons/ui_swing/textpane/LinePosition.java View File

@@ -52,6 +52,18 @@ public class LinePosition {
52 52
         this.endPos = endPos;
53 53
     }
54 54
 
55
+    /**
56
+     * Constructs a new line position.
57
+     *
58
+     * @param position Position to create position from
59
+     */
60
+    public LinePosition(final LinePosition position) {
61
+        this.startLine = position.getStartLine();
62
+        this.endLine = position.getEndLine();
63
+        this.startPos = position.getStartPos();
64
+        this.endPos = position.getEndPos();
65
+    }
66
+
55 67
     /**
56 68
      * Returns the end line for this position.
57 69
      * 

+ 13
- 0
src/com/dmdirc/addons/ui_swing/textpane/MouseEventType.java View File

@@ -0,0 +1,13 @@
1
+
2
+package com.dmdirc.addons.ui_swing.textpane;
3
+
4
+/**
5
+ * Selection event types.
6
+ */
7
+enum MouseEventType {
8
+
9
+    /** Mouse clicked. */
10
+    CLICK, /** Mouse dragged. */
11
+    DRAG, /** Mouse released. */
12
+    RELEASE
13
+}

+ 35
- 364
src/com/dmdirc/addons/ui_swing/textpane/TextPane.java View File

@@ -23,12 +23,7 @@
23 23
 package com.dmdirc.addons.ui_swing.textpane;
24 24
 
25 25
 import com.dmdirc.FrameContainer;
26
-import com.dmdirc.logger.ErrorLevel;
27
-import com.dmdirc.logger.Logger;
28
-import com.dmdirc.ui.messages.IRCTextAttribute;
29
-import com.dmdirc.ui.messages.Styliser;
30 26
 
31
-import java.awt.Dimension;
32 27
 import java.awt.Point;
33 28
 import java.awt.Toolkit;
34 29
 import java.awt.datatransfer.StringSelection;
@@ -39,24 +34,9 @@ import java.awt.event.MouseMotionAdapter;
39 34
 import java.awt.event.MouseMotionListener;
40 35
 import java.awt.event.MouseWheelEvent;
41 36
 import java.awt.event.MouseWheelListener;
42
-import java.awt.font.TextAttribute;
43
-import java.text.AttributedCharacterIterator;
44
-import java.text.AttributedString;
45
-import java.util.Enumeration;
46
-import java.util.List;
47 37
 
48 38
 import javax.swing.JComponent;
49 39
 import javax.swing.JScrollBar;
50
-import javax.swing.SwingUtilities;
51
-import javax.swing.UIManager;
52
-import javax.swing.plaf.ComponentUI;
53
-import javax.swing.text.AttributeSet;
54
-import javax.swing.text.BadLocationException;
55
-import javax.swing.text.Element;
56
-import javax.swing.text.StyleConstants.CharacterConstants;
57
-import javax.swing.text.StyleConstants.ColorConstants;
58
-import javax.swing.text.StyleConstants.FontConstants;
59
-import javax.swing.text.StyledDocument;
60 40
 
61 41
 import net.miginfocom.swing.MigLayout;
62 42
 
@@ -81,19 +61,6 @@ public final class TextPane extends JComponent implements AdjustmentListener,
81 61
     /** Parent Frame. */
82 62
     private final FrameContainer frame;
83 63
 
84
-    /** Click types. */
85
-    public enum ClickType {
86
-
87
-        /** Hyperlink. */
88
-        HYPERLINK,
89
-        /** Channel. */
90
-        CHANNEL,
91
-        /** Nickname. */
92
-        NICKNAME,
93
-        /** Normal. */
94
-        NORMAL,
95
-    }
96
-
97 64
     /** 
98 65
      * Creates a new instance of TextPane. 
99 66
      *
@@ -101,27 +68,16 @@ public final class TextPane extends JComponent implements AdjustmentListener,
101 68
      */
102 69
     public TextPane(final FrameContainer frame) {
103 70
         super();
104
-        
105 71
         setUI(new TextPaneUI());
106 72
 
107 73
         this.frame = frame;
108
-
109 74
         document = new IRCDocument();
110 75
 
111
-        setMinimumSize(new Dimension(0, 0));
112
-
113 76
         setLayout(new MigLayout("fill"));
114
-
115 77
         canvas = new TextPaneCanvas(this, document);
116
-
117 78
         add(canvas, "dock center");
118
-
119
-
120 79
         scrollBar = new JScrollBar(JScrollBar.VERTICAL);
121 80
         add(scrollBar, "dock east");
122
-
123
-        setAutoscrolls(true);
124
-
125 81
         scrollBar.setMaximum(document.getNumLines());
126 82
         scrollBar.setBlockIncrement(10);
127 83
         scrollBar.setUnitIncrement(1);
@@ -129,177 +85,36 @@ public final class TextPane extends JComponent implements AdjustmentListener,
129 85
 
130 86
         addMouseWheelListener(this);
131 87
         document.addIRCDocumentListener(this);
88
+        setAutoscrolls(true);
132 89
 
133 90
         MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
134 91
 
135 92
             /** {@inheritDoc} */
136 93
             @Override
137 94
             public void mouseDragged(MouseEvent e) {
138
-                if (e.getXOnScreen() > getLocationOnScreen().getX() && e.getXOnScreen() < (getLocationOnScreen().
95
+                if (e.getXOnScreen() > getLocationOnScreen().getX() && e.
96
+                        getXOnScreen() < (getLocationOnScreen().
139 97
                         getX() + getWidth()) && e.getModifiersEx() ==
140
-                        MouseEvent.BUTTON1_DOWN_MASK) {
98
+                                                MouseEvent.BUTTON1_DOWN_MASK) {
141 99
                     if (getLocationOnScreen().getY() > e.getYOnScreen()) {
142 100
                         setScrollBarPosition(scrollBar.getValue() - 1);
143
-                    } else if (getLocationOnScreen().getY() + getHeight() <
144
-                            e.getYOnScreen()) {
101
+                    }
102
+                    else if (getLocationOnScreen().getY() + getHeight() <
103
+                             e.getYOnScreen()) {
145 104
                         setScrollBarPosition(scrollBar.getValue() + 1);
146 105
                     }
147
-                    canvas.highlightEvent(TextPaneCanvas.MouseEventType.DRAG, e);
106
+                    canvas.highlightEvent(MouseEventType.DRAG, e);
148 107
                 }
149 108
             }
150 109
         };
151 110
         addMouseMotionListener(doScrollRectToVisible);
152 111
     }
153
-    
112
+
154 113
     /** {@inheritDoc} */
155 114
     @Override
156 115
     public void updateUI() {
157 116
         setUI(new TextPaneUI());
158 117
     }
159
-    
160
-    /** {@inheritDoc} */
161
-    @Override
162
-    public void setUI(final ComponentUI ui) {
163
-        super.setUI(new TextPaneUI());
164
-    }
165
-
166
-    /**
167
-     * Adds styled text to the textpane.
168
-     * @param text styled text to add
169
-     */
170
-    public void addText(final AttributedString text) {
171
-        document.addText(text);
172
-    }
173
-
174
-    /**
175
-     * Adds styled text to the textpane.
176
-     * @param text styled text to add
177
-     */
178
-    public void addText(final List<AttributedString> text) {
179
-        document.addText(text);
180
-    }
181
-
182
-    /**
183
-     * Stylises the specified string and adds it to the passed TextPane.
184
-     *
185
-     * @param string The line to be stylised and added
186
-     */
187
-    public void addStyledString(final String string) {
188
-        addStyledString(new String[]{string,});
189
-    }
190
-
191
-    /**
192
-     * Stylises the specified string and adds it to the passed TextPane.
193
-     *
194
-     * @param strings The strings to be stylised and added to a line
195
-     */
196
-    public void addStyledString(final String[] strings) {
197
-        addText(styledDocumentToAttributedString(
198
-                Styliser.getStyledString(strings)));
199
-    }
200
-
201
-    /**
202
-     * Converts a StyledDocument into an AttributedString.
203
-     *
204
-     * @param doc StyledDocument to convert
205
-     *
206
-     * @return AttributedString representing the specified StyledDocument
207
-     */
208
-    public static AttributedString styledDocumentToAttributedString(
209
-            final StyledDocument doc) {
210
-        //Now lets get hacky, loop through the styled document and add all 
211
-        //styles to an attributedString
212
-        AttributedString attString = null;
213
-        final Element line = doc.getParagraphElement(0);
214
-        try {
215
-            attString = new AttributedString(line.getDocument().getText(0,
216
-                    line.getDocument().getLength()));
217
-        } catch (BadLocationException ex) {
218
-            Logger.userError(ErrorLevel.MEDIUM,
219
-                    "Unable to insert styled string: " + ex.getMessage());
220
-        }
221
-
222
-        if (attString.getIterator().getEndIndex() != 0) {
223
-            attString.addAttribute(TextAttribute.SIZE,
224
-                    UIManager.getFont("TextPane.font").getSize());
225
-            attString.addAttribute(TextAttribute.FAMILY,
226
-                    UIManager.getFont("TextPane.font").getFamily());
227
-        }
228
-
229
-        for (int i = 0; i < line.getElementCount(); i++) {
230
-            final Element element = line.getElement(i);
231
-
232
-            final AttributeSet as = element.getAttributes();
233
-            final Enumeration<?> ae = as.getAttributeNames();
234
-
235
-            while (ae.hasMoreElements()) {
236
-                final Object attrib = ae.nextElement();
237
-
238
-                if (attrib == IRCTextAttribute.HYPERLINK) {
239
-                    //Hyperlink
240
-                    attString.addAttribute(IRCTextAttribute.HYPERLINK,
241
-                            as.getAttribute(attrib), element.getStartOffset(),
242
-                            element.getEndOffset());
243
-                } else if (attrib == IRCTextAttribute.NICKNAME) {
244
-                    //Nicknames
245
-                    attString.addAttribute(IRCTextAttribute.NICKNAME,
246
-                            as.getAttribute(attrib), element.getStartOffset(),
247
-                            element.getEndOffset());
248
-                } else if (attrib == IRCTextAttribute.CHANNEL) {
249
-                    //Channels
250
-                    attString.addAttribute(IRCTextAttribute.CHANNEL,
251
-                            as.getAttribute(attrib), element.getStartOffset(),
252
-                            element.getEndOffset());
253
-                } else if (attrib == ColorConstants.Foreground) {
254
-                    //Foreground
255
-                    attString.addAttribute(TextAttribute.FOREGROUND,
256
-                            as.getAttribute(attrib), element.getStartOffset(),
257
-                            element.getEndOffset());
258
-                } else if (attrib == ColorConstants.Background) {
259
-                    //Background
260
-                    attString.addAttribute(TextAttribute.BACKGROUND,
261
-                            as.getAttribute(attrib), element.getStartOffset(),
262
-                            element.getEndOffset());
263
-                } else if (attrib == FontConstants.Bold) {
264
-                    //Bold
265
-                    attString.addAttribute(TextAttribute.WEIGHT,
266
-                            TextAttribute.WEIGHT_BOLD, element.getStartOffset(),
267
-                            element.getEndOffset());
268
-                } else if (attrib == FontConstants.Family) {
269
-                    //Family
270
-                    attString.addAttribute(TextAttribute.FAMILY,
271
-                            as.getAttribute(attrib), element.getStartOffset(),
272
-                            element.getEndOffset());
273
-                } else if (attrib == FontConstants.Italic) {
274
-                    //italics
275
-                    attString.addAttribute(TextAttribute.POSTURE,
276
-                            TextAttribute.POSTURE_OBLIQUE,
277
-                            element.getStartOffset(),
278
-                            element.getEndOffset());
279
-                } else if (attrib == CharacterConstants.Underline) {
280
-                    //Underline
281
-                    attString.addAttribute(TextAttribute.UNDERLINE,
282
-                            TextAttribute.UNDERLINE_ON, element.getStartOffset(),
283
-                            element.getEndOffset());
284
-                } else if (attrib == IRCTextAttribute.SMILEY) {
285
-                    /* Lets avoid showing broken smileys shall we!
286
-                    final Image image = IconManager.getIconManager().getImage((String) as.getAttribute(attrib)).
287
-                            getScaledInstance(14, 14, Image.SCALE_DEFAULT);
288
-                    ImageGraphicAttribute iga = new ImageGraphicAttribute(image, 
289
-                            (int) BOTTOM_ALIGNMENT, 5, 5);
290
-                    attString.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga,
291
-                            element.getStartOffset(), element.getEndOffset());
292
-                    */
293
-                }
294
-            }
295
-        }
296
-
297
-        if (attString.getIterator().getEndIndex() == 0) {
298
-            return new AttributedString("\n");
299
-        }
300
-
301
-        return attString;
302
-    }
303 118
 
304 119
     /**
305 120
      * Sets the new position for the scrollbar and the associated position
@@ -311,21 +126,6 @@ public final class TextPane extends JComponent implements AdjustmentListener,
311 126
         canvas.setScrollBarPosition(position);
312 127
     }
313 128
 
314
-    /**
315
-     * Enables or disabled the scrollbar for the textpane.
316
-     *
317
-     * @param enabled State for the scrollbar
318
-     */
319
-    public void setScrollEnabled(final boolean enabled) {
320
-        SwingUtilities.invokeLater(new Runnable() {
321
-
322
-            @Override
323
-            public void run() {
324
-                scrollBar.setEnabled(enabled);
325
-            }
326
-        });
327
-    }
328
-
329 129
     /**
330 130
      * Returns the last visible line in the textpane.
331 131
      *
@@ -335,26 +135,6 @@ public final class TextPane extends JComponent implements AdjustmentListener,
335 135
         return scrollBar.getValue();
336 136
     }
337 137
 
338
-    /**
339
-     * Returns the line count in the textpane.
340
-     *
341
-     * @return Line count
342
-     */
343
-    public int getNumLines() {
344
-        return document.getNumLines();
345
-    }
346
-
347
-    /**
348
-     * Returns the specified line in the textpane.
349
-     *
350
-     * @param line Line to return
351
-     *
352
-     * @return AttributedString at the specified line
353
-     */
354
-    public AttributedString getLine(final int line) {
355
-        return document.getLine(line);
356
-    }
357
-
358 138
     /**
359 139
      * Sets the scrollbar's maximum position. If the current position is
360 140
      * within <code>linesAllowed</code> of the end of the document, the
@@ -372,8 +152,9 @@ public final class TextPane extends JComponent implements AdjustmentListener,
372 152
 
373 153
         scrollBar.setMaximum(lines);
374 154
 
375
-        if (!scrollBar.getValueIsAdjusting() && scrollBar.getValue() == lines -
376
-                linesAllowed) {
155
+        if (!scrollBar.getValueIsAdjusting() && scrollBar.getValue() ==
156
+                                                lines -
157
+                                                linesAllowed) {
377 158
             setScrollBarPosition(lines);
378 159
         }
379 160
     }
@@ -398,7 +179,8 @@ public final class TextPane extends JComponent implements AdjustmentListener,
398 179
         if (scrollBar.isEnabled()) {
399 180
             if (e.getWheelRotation() > 0) {
400 181
                 setScrollBarPosition(scrollBar.getValue() + e.getScrollAmount());
401
-            } else {
182
+            }
183
+            else {
402 184
                 setScrollBarPosition(scrollBar.getValue() - e.getScrollAmount());
403 185
             }
404 186
         }
@@ -431,31 +213,32 @@ public final class TextPane extends JComponent implements AdjustmentListener,
431 213
         final LinePosition selectedRange = canvas.getSelectedRange();
432 214
 
433 215
         for (int i = selectedRange.getStartLine(); i <=
434
-                selectedRange.getEndLine(); i++) {
216
+                                                   selectedRange.getEndLine();
217
+             i++) {
435 218
             if (i != selectedRange.getStartLine()) {
436 219
                 selectedText.append('\n');
437 220
             }
438 221
             if (document.getNumLines() <= i) {
439 222
                 return selectedText.toString();
440 223
             }
441
-            final AttributedCharacterIterator iterator = document.getLine(i).
442
-                    getIterator();
224
+            final String line = document.getLine(i).getText();
443 225
             if (selectedRange.getEndLine() == selectedRange.getStartLine()) {
444 226
                 //loop through range
445
-                selectedText.append(getTextFromLine(iterator,
446
-                        selectedRange.getStartPos(), selectedRange.getEndPos()));
447
-            } else if (i == selectedRange.getStartLine()) {
227
+                selectedText.append(line.substring(selectedRange.getStartPos(),
228
+                                                   selectedRange.getEndPos()));
229
+            }
230
+            else if (i == selectedRange.getStartLine()) {
448 231
                 //loop from start of range to the end
449
-                selectedText.append(getTextFromLine(iterator,
450
-                        selectedRange.getStartPos(), iterator.getEndIndex()));
451
-            } else if (i == selectedRange.getEndLine()) {
232
+                selectedText.append(line.substring(selectedRange.getStartPos(),
233
+                                                   line.length()));
234
+            }
235
+            else if (i == selectedRange.getEndLine()) {
452 236
                 //loop from start to end of range
453
-                selectedText.append(getTextFromLine(iterator, 0,
454
-                        selectedRange.getEndPos()));
455
-            } else {
237
+                selectedText.append(line.substring(0, selectedRange.getEndPos()));
238
+            }
239
+            else {
456 240
                 //loop the whole line
457
-                selectedText.append(getTextFromLine(iterator, 0,
458
-                        iterator.getEndIndex()));
241
+                selectedText.append(line);
459 242
             }
460 243
         }
461 244
 
@@ -479,7 +262,7 @@ public final class TextPane extends JComponent implements AdjustmentListener,
479 262
     public boolean hasSelectedRange() {
480 263
         final LinePosition selectedRange = canvas.getSelectedRange();
481 264
         return !(selectedRange.getStartLine() == selectedRange.getEndLine() &&
482
-                selectedRange.getStartPos() == selectedRange.getEndPos());
265
+                 selectedRange.getStartPos() == selectedRange.getEndPos());
483 266
     }
484 267
 
485 268
     /**
@@ -491,120 +274,6 @@ public final class TextPane extends JComponent implements AdjustmentListener,
491 274
         canvas.setSelectedRange(position);
492 275
     }
493 276
 
494
-    /**
495
-     * Returns the entire text from the specified line.
496
-     *
497
-     * @param line line to retrieve text from
498
-     *
499
-     * @return Text from the line
500
-     */
501
-    public String getTextFromLine(final int line) {
502
-        final AttributedCharacterIterator iterator = document.getLine(line).
503
-                getIterator();
504
-        return getTextFromLine(iterator, 0, iterator.getEndIndex(), document);
505
-    }
506
-
507
-    /**
508
-     * Returns the entire text from the specified line.
509
-     *
510
-     * @param line line to retrieve text from
511
-     * @param document Document to retrieve text from
512
-     * 
513
-     * @return Text from the line
514
-     */
515
-    public static String getTextFromLine(final int line,
516
-            final IRCDocument document) {
517
-        final AttributedCharacterIterator iterator = document.getLine(line).
518
-                getIterator();
519
-        return getTextFromLine(iterator, 0, iterator.getEndIndex(), document);
520
-    }
521
-
522
-    /**
523
-     * Returns the range of text from the specified iterator.
524
-     *
525
-     * @param line line to retrieve text from
526
-     * @param start Start index in the iterator
527
-     * @param end End index in the iterator
528
-     *
529
-     * @return Text in the range from the line
530
-     */
531
-    public String getTextFromLine(final int line, final int start,
532
-            final int end) {
533
-        return getTextFromLine(document.getLine(line).getIterator(), start, end,
534
-                document);
535
-    }
536
-
537
-    /**
538
-     * Returns the range of text from the specified iterator.
539
-     *
540
-     * @param line line to retrieve text from
541
-     * @param start Start index in the iterator
542
-     * @param end End index in the iterator
543
-     * @param document Document to retrieve text from
544
-     *
545
-     * @return Text in the range from the line
546
-     */
547
-    public static String getTextFromLine(final int line, final int start,
548
-            final int end, final IRCDocument document) {
549
-        return getTextFromLine(document.getLine(line).getIterator(), start, end,
550
-                document);
551
-    }
552
-
553
-    /**
554
-     * Returns the range of text from the specified iterator.
555
-     *
556
-     * @param iterator iterator to get text from
557
-     *
558
-     * @return Text in the range from the line
559
-     */
560
-    public String getTextFromLine(final AttributedCharacterIterator iterator) {
561
-        return getTextFromLine(iterator, iterator.getBeginIndex(),
562
-                iterator.getEndIndex(), document);
563
-    }
564
-
565
-    /**
566
-     * Returns the range of text from the specified iterator.
567
-     *
568
-     * @param iterator iterator to get text from
569
-     * @param document Document to retrieve text from
570
-     *
571
-     * @return Text in the range from the line
572
-     */
573
-    public static String getTextFromLine(final AttributedCharacterIterator iterator,
574
-            final IRCDocument document) {
575
-        return getTextFromLine(iterator, iterator.getBeginIndex(),
576
-                iterator.getEndIndex(), document);
577
-    }
578
-
579
-    /**
580
-     * Returns the range of text from the specified iterator.
581
-     *
582
-     * @param iterator iterator to get text from
583
-     * @param start Start index in the iterator
584
-     * @param end End index in the iterator
585
-     *
586
-     * @return Text in the range from the line
587
-     */
588
-    public String getTextFromLine(final AttributedCharacterIterator iterator,
589
-            final int start, final int end) {
590
-        return getTextFromLine(iterator, start, end, document);
591
-    }
592
-
593
-    /**
594
-     * Returns the range of text from the specified iterator.
595
-     *
596
-     * @param iterator iterator to get text from
597
-     * @param start Start index in the iterator
598
-     * @param end End index in the iterator
599
-     * @param document Document to retrieve text from
600
-     *
601
-     * @return Text in the range from the line
602
-     */
603
-    public static String getTextFromLine(final AttributedCharacterIterator iterator,
604
-            final int start, final int end, final IRCDocument document) {
605
-        return document.getLineText(iterator, start, end);
606
-    }
607
-
608 277
     /**
609 278
      * Returns the type of text this click represents.
610 279
      * 
@@ -629,9 +298,11 @@ public final class TextPane extends JComponent implements AdjustmentListener,
629 298
             return "";
630 299
         }
631 300
         final int[] indexes =
632
-                canvas.getSurroundingWordIndexes(getTextFromLine(lineNumber),
633
-                index);
634
-        return getTextFromLine(lineNumber, indexes[0], indexes[1]);
301
+                    canvas.getSurroundingWordIndexes(document.getLine(lineNumber).
302
+                getText(),
303
+                                                     index);
304
+        return document.getLine(lineNumber).getText().substring(indexes[0],
305
+                                                                indexes[1]);
635 306
     }
636 307
 
637 308
     /**

+ 135
- 153
src/com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas.java View File

@@ -23,7 +23,6 @@
23 23
 package com.dmdirc.addons.ui_swing.textpane;
24 24
 
25 25
 import com.dmdirc.ui.messages.IRCTextAttribute;
26
-import com.dmdirc.addons.ui_swing.textpane.TextPane.ClickType;
27 26
 
28 27
 import java.awt.Cursor;
29 28
 import java.awt.Graphics;
@@ -70,28 +69,10 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
70 69
     private final Map<TextLayout, LineInfo> textLayouts;
71 70
     /** Line height. */
72 71
     private final int lineHeight;
73
-
74
-    /** Selection event types. */
75
-    protected enum MouseEventType {
76
-
77
-        /** Mouse clicked. */
78
-        CLICK,
79
-        /** Mouse dragged. */
80
-        DRAG,
81
-        /** Mouse released. */
82
-        RELEASE,
83
-    }
84
-
85 72
     /** position of the scrollbar. */
86 73
     private int scrollBarPosition;
87
-    /** Start line of the selection. */
88
-    private int selStartLine;
89
-    /** Start character of the selection. */
90
-    private int selStartChar;
91
-    /** End line of the selection. */
92
-    private int selEndLine;
93
-    /** End character of the selection. */
94
-    private int selEndChar;
74
+    /** Selection. */
75
+    private LinePosition selection;
95 76
     /** First visible line. */
96 77
     private int firstVisibleLine;
97 78
     /** Last visible line. */
@@ -116,6 +97,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
116 97
         textLayouts = new HashMap<TextLayout, LineInfo>();
117 98
         positions = new HashMap<Rectangle, TextLayout>();
118 99
         lineWrap = new HashMap<Integer, Integer>();
100
+        selection = new LinePosition(-1, -1, -1, -1);
119 101
         addMouseListener(this);
120 102
         addMouseMotionListener(this);
121 103
         addComponentListener(this);
@@ -141,10 +123,6 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
141 123
         float drawPosY = formatHeight;
142 124
         int startLine = scrollBarPosition;
143 125
 
144
-        int useStartLine;
145
-        int useStartChar;
146
-        int useEndLine;
147
-        int useEndChar;
148 126
         int paragraphStart;
149 127
         int paragraphEnd;
150 128
         LineBreakMeasurer lineMeasurer;
@@ -155,14 +133,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
155 133
         textLayouts.clear();
156 134
         positions.clear();
157 135
 
158
-        //check theres something to draw
159
-        if (document.getNumLines() == 0) {
160
-            setCursor(Cursor.getDefaultCursor());
161
-            return;
162
-        }
163
-
164
-        //check there is some space to draw in
165
-        if (formatWidth < 1) {
136
+        //check theres something to draw and theres some space to draw in
137
+        if (document.getNumLines() == 0 || formatWidth < 1) {
166 138
             setCursor(Cursor.getDefaultCursor());
167 139
             return;
168 140
         }
@@ -180,35 +152,14 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
180 152
         lastVisibleLine = startLine;
181 153
         firstVisibleLine = startLine;
182 154
 
183
-        if (selStartLine > selEndLine) {
184
-            // Swap both
185
-            useStartLine = selEndLine;
186
-            useStartChar = selEndChar;
187
-            useEndLine = selStartLine;
188
-            useEndChar = selStartChar;
189
-        } else if (selStartLine == selEndLine && selStartChar > selEndChar) {
190
-            // Just swap the chars
191
-            useStartLine = selStartLine;
192
-            useStartChar = selEndChar;
193
-            useEndLine = selEndLine;
194
-            useEndChar = selStartChar;
195
-        } else {
196
-            // Swap nothing
197
-            useStartLine = selStartLine;
198
-            useStartChar = selStartChar;
199
-            useEndLine = selEndLine;
200
-            useEndChar = selEndChar;
201
-        }
202
-
203 155
         // Iterate through the lines
204 156
         for (int i = startLine; i >= 0; i--) {
205 157
             float drawPosX;
206
-            final AttributedCharacterIterator iterator = document.getLine(i).
207
-                    getIterator();
158
+            final AttributedCharacterIterator iterator = document.getStyledLine(i);
208 159
             paragraphStart = iterator.getBeginIndex();
209 160
             paragraphEnd = iterator.getEndIndex();
210 161
             lineMeasurer = new LineBreakMeasurer(iterator,
211
-                    g.getFontRenderContext());
162
+                                                 g.getFontRenderContext());
212 163
             lineMeasurer.setPosition(paragraphStart);
213 164
 
214 165
             final int wrappedLine;
@@ -220,7 +171,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
220 171
             } else {
221 172
                 //get it and populate the cache
222 173
                 wrappedLine = getNumWrappedLines(lineMeasurer,
223
-                        paragraphStart, paragraphEnd, formatWidth);
174
+                                                 paragraphStart, paragraphEnd,
175
+                                                 formatWidth);
224 176
                 lineWrap.put(i, wrappedLine);
225 177
             }
226 178
 
@@ -254,12 +206,12 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
254 206
                     g.setColor(textPane.getForeground());
255 207
 
256 208
                     layout.draw(g, drawPosX, drawPosY + lineHeight / 2f);
257
-                    doHighlight(i, useStartLine, useEndLine, useStartChar,
258
-                            useEndChar, chars, layout, g, drawPosY, drawPosX);
209
+                    doHighlight(i, chars, layout, g, drawPosY, drawPosX);
259 210
                     firstVisibleLine = i;
260 211
                     textLayouts.put(layout, new LineInfo(i, j));
261 212
                     positions.put(new Rectangle(0, (int) drawPosY,
262
-                            (int) formatWidth + 6, lineHeight), layout);
213
+                                                (int) formatWidth + 6,
214
+                                                lineHeight), layout);
263 215
                 }
264 216
 
265 217
                 j++;
@@ -286,8 +238,9 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
286 238
      * @return Number of times the line wraps
287 239
      */
288 240
     private int getNumWrappedLines(final LineBreakMeasurer lineMeasurer,
289
-            final int paragraphStart, final int paragraphEnd,
290
-            final float formatWidth) {
241
+                                   final int paragraphStart,
242
+                                   final int paragraphEnd,
243
+                                   final float formatWidth) {
291 244
         int wrappedLine = 0;
292 245
 
293 246
         while (lineMeasurer.getPosition() < paragraphEnd) {
@@ -305,20 +258,41 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
305 258
      * Redraws the text that has been highlighted.
306 259
      *
307 260
      * @param line Line number
308
-     * @param startLine Selection start line
309
-     * @param endLine Selection end line
310
-     * @param startChar Selection start char
311
-     * @param endChar Selection end char
312 261
      * @param chars Number of characters so far in the line
313 262
      * @param layout Current line textlayout
314 263
      * @param g Graphics surface to draw highlight on
315 264
      * @param drawPosY current y location of the line
316 265
      * @param drawPosX current x location of the line
317 266
      */
318
-    private void doHighlight(final int line, final int startLine,
319
-            final int endLine, final int startChar, final int endChar,
320
-            final int chars, final TextLayout layout, final Graphics2D g,
321
-            final float drawPosY, final float drawPosX) {
267
+    private void doHighlight(final int line, final int chars,
268
+                             final TextLayout layout, final Graphics2D g,
269
+                             final float drawPosY, final float drawPosX) {
270
+        int startLine;
271
+        int startChar;
272
+        int endLine;
273
+        int endChar;
274
+
275
+        if (selection.getStartLine() > selection.getEndLine()) {
276
+            // Swap both
277
+            startLine = selection.getEndLine();
278
+            startChar = selection.getEndPos();
279
+            endLine = selection.getStartLine();
280
+            endChar = selection.getStartPos();
281
+        } else if (selection.getStartLine() == selection.getEndLine() &&
282
+                   selection.getStartPos() > selection.getEndPos()) {
283
+            // Just swap the chars
284
+            startLine = selection.getStartLine();
285
+            startChar = selection.getEndPos();
286
+            endLine = selection.getEndLine();
287
+            endChar = selection.getStartPos();
288
+        } else {
289
+            // Swap nothing
290
+            startLine = selection.getStartLine();
291
+            startChar = selection.getStartPos();
292
+            endLine = selection.getEndLine();
293
+            endChar = selection.getEndPos();
294
+        }
295
+
322 296
         //Does this line need highlighting?
323 297
         if (startLine <= line && endLine >= line) {
324 298
             int firstChar;
@@ -340,9 +314,10 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
340 314
 
341 315
             // If the selection includes the chars we're showing
342 316
             if (lastChar > chars && firstChar < chars +
343
-                    layout.getCharacterCount()) {
317
+                                                layout.getCharacterCount()) {
344 318
                 final String text =
345
-                        textPane.getTextFromLine(line).substring(firstChar,
319
+                             document.getLine(line).getText().substring(
320
+                        firstChar,
346 321
                         lastChar);
347 322
 
348 323
                 if (text.isEmpty()) {
@@ -350,17 +325,22 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
350 325
                 }
351 326
 
352 327
                 final int trans = (int) (lineHeight / 2f + drawPosY);
353
-                final AttributedString as = new AttributedString(
354
-                        textPane.getLine(line).getIterator(), firstChar,
355
-                        lastChar);
328
+                final AttributedCharacterIterator iterator = document.
329
+                        getStyledLine(line);
330
+                final AttributedString as = new AttributedString(iterator,
331
+                                                                 firstChar,
332
+                                                                 lastChar);
356 333
                 as.addAttribute(TextAttribute.FOREGROUND,
357
-                        textPane.getBackground());
334
+                                textPane.getBackground());
358 335
                 as.addAttribute(TextAttribute.BACKGROUND,
359
-                        textPane.getForeground());
336
+                                textPane.getForeground());
360 337
                 final TextLayout newLayout = new TextLayout(as.getIterator(),
361
-                        g.getFontRenderContext());
338
+                                                            g.
339
+                        getFontRenderContext());
362 340
                 final Shape shape = layout.getLogicalHighlightShape(firstChar -
363
-                        chars, lastChar - chars);
341
+                                                                    chars,
342
+                                                                    lastChar -
343
+                                                                    chars);
364 344
 
365 345
                 if (firstChar != 0) {
366 346
                     g.translate(shape.getBounds().getX(), 0);
@@ -387,7 +367,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
387 367
             }
388 368
         }
389 369
     }
390
-    
370
+
391 371
     /**
392 372
      * Returns the current scroll bar position.
393 373
      * 
@@ -411,28 +391,29 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
411 391
         final LineInfo lineInfo = getClickPosition(getMousePosition());
412 392
 
413 393
         if (lineInfo.getLine() != -1) {
414
-            clickedText = textPane.getTextFromLine(lineInfo.getLine());
394
+            clickedText = document.getLine(lineInfo.getLine()).getText();
415 395
 
416 396
             if (lineInfo.getIndex() == -1) {
417 397
                 start = -1;
418 398
                 end = -1;
419 399
             } else {
420
-                final int[] extent = getSurroundingWordIndexes(clickedText,
421
-                        lineInfo.getIndex());
400
+                final int[] extent =
401
+                            getSurroundingWordIndexes(clickedText,
402
+                                                      lineInfo.getIndex());
422 403
                 start = extent[0];
423 404
                 end = extent[1];
424 405
             }
425 406
 
426 407
             if (e.getClickCount() == 2) {
427
-                selStartLine = lineInfo.getLine();
428
-                selEndLine = lineInfo.getLine();
429
-                selStartChar = start;
430
-                selEndChar = end;
408
+                selection.setStartLine(lineInfo.getLine());
409
+                selection.setEndLine(lineInfo.getLine());
410
+                selection.setStartPos(start);
411
+                selection.setEndPos(end);
431 412
             } else if (e.getClickCount() == 3) {
432
-                selStartLine = lineInfo.getLine();
433
-                selEndLine = lineInfo.getLine();
434
-                selStartChar = 0;
435
-                selEndChar = clickedText.length();
413
+                selection.setStartLine(lineInfo.getLine());
414
+                selection.setEndLine(lineInfo.getLine());
415
+                selection.setStartPos(0);
416
+                selection.setEndPos(clickedText.length());
436 417
             }
437 418
         }
438 419
 
@@ -449,26 +430,23 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
449 430
      */
450 431
     public ClickType getClickType(final LineInfo lineInfo) {
451 432
         if (lineInfo.getLine() != -1) {
452
-            final AttributedCharacterIterator iterator = document.getLine(lineInfo.getLine()).
453
-                    getIterator();
454
-            if (lineInfo.getIndex() <= iterator.getEndIndex()) {
455
-                iterator.setIndex(lineInfo.getIndex());
456
-                Object linkattr =
457
-                        iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
458
-                if (linkattr instanceof String) {
459
-                    return ClickType.HYPERLINK;
460
-                }
461
-                linkattr = iterator.getAttributes().get(IRCTextAttribute.CHANNEL);
462
-                if (linkattr instanceof String) {
463
-                    return ClickType.CHANNEL;
464
-                }
465
-                linkattr = iterator.getAttributes().get(IRCTextAttribute.NICKNAME);
466
-                if (linkattr instanceof String) {
467
-                    return ClickType.NICKNAME;
468
-                }
433
+            final AttributedCharacterIterator iterator = document.getStyledLine(
434
+                    lineInfo.getLine());
435
+            iterator.setIndex(lineInfo.getIndex());
436
+            Object linkattr =
437
+                   iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
438
+            if (linkattr instanceof String) {
439
+                return ClickType.HYPERLINK;
440
+            }
441
+            linkattr = iterator.getAttributes().get(IRCTextAttribute.CHANNEL);
442
+            if (linkattr instanceof String) {
443
+                return ClickType.CHANNEL;
444
+            }
445
+            linkattr = iterator.getAttributes().get(IRCTextAttribute.NICKNAME);
446
+            if (linkattr instanceof String) {
447
+                return ClickType.NICKNAME;
469 448
             }
470 449
         }
471
-
472 450
         return ClickType.NORMAL;
473 451
     }
474 452
 
@@ -481,11 +459,11 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
481 459
      */
482 460
     public Object getAttributeValueAtPoint(LineInfo lineInfo) {
483 461
         if (lineInfo.getLine() != -1) {
484
-            final AttributedCharacterIterator iterator = document.getLine(lineInfo.getLine()).
485
-                    getIterator();
462
+            final AttributedCharacterIterator iterator = document.getStyledLine(
463
+                    lineInfo.getLine());
486 464
             iterator.setIndex(lineInfo.getIndex());
487 465
             Object linkattr =
488
-                    iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
466
+                   iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
489 467
             if (linkattr instanceof String) {
490 468
                 return linkattr;
491 469
             }
@@ -511,7 +489,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
511 489
      * @return Indexes of the word surrounding the index (start, end)
512 490
      */
513 491
     protected int[] getSurroundingWordIndexes(final String text,
514
-            final int index) {
492
+                                              final int index) {
515 493
         final int start = getSurroundingWordStart(text, index);
516 494
         final int end = getSurroundingWordEnd(text, index);
517 495
 
@@ -616,7 +594,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
616 594
      */
617 595
     @Override
618 596
     public void mouseEntered(final MouseEvent e) {
619
-    //Ignore
597
+        //Ignore
620 598
     }
621 599
 
622 600
     /** 
@@ -626,7 +604,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
626 604
      */
627 605
     @Override
628 606
     public void mouseExited(final MouseEvent e) {
629
-    //Ignore
607
+        //Ignore
630 608
     }
631 609
 
632 610
     /** 
@@ -641,18 +619,19 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
641 619
 
642 620
     /** Checks for a link under the cursor and sets appropriately. */
643 621
     private void checkForLink() {
644
-        final LineInfo info = getClickPosition(getMousePosition());
622
+        final LineInfo lineInfo = getClickPosition(getMousePosition());
645 623
 
646
-        if (info.getLine() != -1 && document.getLine(info.getLine()) != null) {
647
-            final AttributedCharacterIterator iterator = document.getLine(info.getLine()).
648
-                    getIterator();
649
-            if (info.getIndex() < iterator.getBeginIndex() || info.getIndex() >
650
-                    iterator.getEndIndex()) {
624
+        if (lineInfo.getLine() != -1 && document.getLine(lineInfo.getLine()) !=
625
+                                        null) {
626
+            final AttributedCharacterIterator iterator = document.getStyledLine(
627
+                    lineInfo.getLine());
628
+            if (lineInfo.getIndex() < iterator.getBeginIndex() ||
629
+                lineInfo.getIndex() > iterator.getEndIndex()) {
651 630
                 return;
652 631
             }
653
-            iterator.setIndex(info.getIndex());
632
+            iterator.setIndex(lineInfo.getIndex());
654 633
             Object linkattr =
655
-                    iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
634
+                   iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
656 635
             if (linkattr instanceof String) {
657 636
                 setCursor(HAND_CURSOR);
658 637
                 return;
@@ -680,7 +659,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
680 659
      * @param e responsible mouse event
681 660
      */
682 661
     protected void highlightEvent(final MouseEventType type,
683
-            final MouseEvent e) {
662
+                                  final MouseEvent e) {
684 663
         if (isVisible()) {
685 664
             Point point = e.getLocationOnScreen();
686 665
             SwingUtilities.convertPointFromScreen(point, this);
@@ -691,17 +670,18 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
691 670
                     point.setLocation(bounds.getX() + 3, point.getY());
692 671
                 } else if (mousePos.getX() > (bounds.getX() + bounds.getWidth())) {
693 672
                     point.setLocation(bounds.getX() + bounds.getWidth() - 3,
694
-                            point.getY());
673
+                                      point.getY());
695 674
                 }
696 675
                 if (mousePos.getY() < bounds.getY()) {
697 676
                     point.setLocation(point.getX(), bounds.getY() + 6);
698 677
                 } else if (mousePos.getY() >
699
-                        (bounds.getY() + bounds.getHeight())) {
678
+                           (bounds.getY() + bounds.getHeight())) {
700 679
                     //Nice text selection behaviour
701 680
                     //point.setLocation(point.getX(), bounds.getY() +
702 681
                     //        bounds.getHeight() - 6);
703
-                    point.setLocation(bounds.getX() + bounds.getWidth() - 3, bounds.getY() +
704
-                            bounds.getHeight() - 6);
682
+                    point.setLocation(bounds.getX() + bounds.getWidth() - 3,
683
+                                      bounds.getY() +
684
+                                      bounds.getHeight() - 6);
705 685
                 }
706 686
             }
707 687
             final LineInfo info = getClickPosition(point);
@@ -715,11 +695,11 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
715 695
             }
716 696
             if (info.getLine() != -1 && info.getPart() != -1) {
717 697
                 if (type == MouseEventType.CLICK) {
718
-                    selStartLine = info.getLine();
719
-                    selStartChar = info.getIndex();
698
+                    selection.setStartLine(info.getLine());
699
+                    selection.setStartPos(info.getIndex());
720 700
                 }
721
-                selEndLine = info.getLine();
722
-                selEndChar = info.getIndex();
701
+                selection.setEndLine(info.getLine());
702
+                selection.setEndPos(info.getIndex());
723 703
 
724 704
                 repaint();
725 705
             }
@@ -748,7 +728,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
748 728
             }
749 729
 
750 730
             pos = getHitPosition(lineNumber, linePart, (int) point.getX(),
751
-                    (int) point.getY());
731
+                                 (int) point.getY());
752 732
         }
753 733
 
754 734
         return new LineInfo(lineNumber, linePart, pos);
@@ -765,7 +745,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
765 745
      * @return Hit position
766 746
      */
767 747
     private int getHitPosition(final int lineNumber, final int linePart,
768
-            final int x, final int y) {
748
+                               final int x, final int y) {
769 749
         int pos = 0;
770 750
 
771 751
         for (Map.Entry<Rectangle, TextLayout> entry : positions.entrySet()) {
@@ -773,9 +753,9 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
773 753
                 if (textLayouts.get(entry.getValue()).getPart() < linePart) {
774 754
                     pos += entry.getValue().getCharacterCount();
775 755
                 } else if (textLayouts.get(entry.getValue()).getPart() ==
776
-                        linePart) {
756
+                           linePart) {
777 757
                     final TextHitInfo hit = entry.getValue().hitTestChar(x - 6,
778
-                            y);
758
+                                                                         y);
779 759
                     pos += hit.getInsertionIndex();
780 760
                 }
781 761
             }
@@ -790,25 +770,30 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
790 770
      * @return Selected range info
791 771
      */
792 772
     protected LinePosition getSelectedRange() {
793
-        if (selStartLine > selEndLine) {
773
+        if (selection.getStartLine() > selection.getEndLine()) {
794 774
             // Swap both
795
-            return new LinePosition(selEndLine, selEndChar, selStartLine,
796
-                    selStartChar);
797
-        } else if (selStartLine == selEndLine && selStartChar > selEndChar) {
775
+            return new LinePosition(selection.getEndLine(),
776
+                                    selection.getEndPos(), selection.
777
+                    getStartLine(),
778
+                                    selection.getStartPos());
779
+        } else if (selection.getStartLine() == selection.getEndLine() &&
780
+                   selection.getStartPos() > selection.getEndPos()) {
798 781
             // Just swap the chars
799
-            return new LinePosition(selStartLine, selEndChar, selEndLine,
800
-                    selStartChar);
782
+            return new LinePosition(selection.getStartLine(), selection.
783
+                    getEndPos(), selection.getEndLine(),
784
+                                    selection.getStartPos());
801 785
         } else {
802 786
             // Swap nothing
803
-            return new LinePosition(selStartLine, selStartChar, selEndLine,
804
-                    selEndChar);
787
+            return new LinePosition(selection.getStartLine(), selection.
788
+                    getStartPos(), selection.getEndLine(),
789
+                                    selection.getEndPos());
805 790
         }
806 791
     }
807 792
 
808 793
     /** Clears the selection. */
809 794
     protected void clearSelection() {
810
-        selEndLine = selStartLine;
811
-        selEndChar = selStartChar;
795
+        selection.setEndLine(selection.getStartLine());
796
+        selection.setEndPos(selection.getStartPos());
812 797
         if (isVisible()) {
813 798
             repaint();
814 799
         }
@@ -820,10 +805,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
820 805
      * @param position Line position
821 806
      */
822 807
     public void setSelectedRange(final LinePosition position) {
823
-        selStartLine = position.getStartLine();
824
-        selStartChar = position.getStartPos();
825
-        selEndLine = position.getEndLine();
826
-        selEndChar = position.getEndPos();
808
+        selection = new LinePosition(position);
827 809
         if (isVisible()) {
828 810
             repaint();
829 811
         }
@@ -868,7 +850,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
868 850
      */
869 851
     @Override
870 852
     public void componentMoved(final ComponentEvent e) {
871
-    //Ignore
853
+        //Ignore
872 854
     }
873 855
 
874 856
     /** 
@@ -878,7 +860,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
878 860
      */
879 861
     @Override
880 862
     public void componentShown(final ComponentEvent e) {
881
-    //Ignore
863
+        //Ignore
882 864
     }
883 865
 
884 866
     /** 
@@ -888,7 +870,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
888 870
      */
889 871
     @Override
890 872
     public void componentHidden(final ComponentEvent e) {
891
-    //Ignore
873
+        //Ignore
892 874
     }
893 875
 
894 876
     /** Clears the line wrapping cache. */

+ 29
- 1
src/com/dmdirc/addons/ui_swing/textpane/TextPaneUI.java View File

@@ -22,10 +22,16 @@
22 22
 
23 23
 package com.dmdirc.addons.ui_swing.textpane;
24 24
 
25
+import java.awt.Graphics;
26
+import java.awt.Graphics2D;
27
+
25 28
 import javax.swing.JComponent;
26 29
 import javax.swing.UIManager;
27 30
 import javax.swing.plaf.ComponentUI;
28 31
 
32
+/**
33
+ * TextPane UI
34
+ */
29 35
 public class TextPaneUI extends ComponentUI {
30 36
 
31 37
     /** {@inheritDoc} */
@@ -33,5 +39,27 @@ public class TextPaneUI extends ComponentUI {
33 39
     public void installUI(final JComponent c) {
34 40
         c.setBorder(UIManager.getBorder("TextField.border"));
35 41
     }
36
-    
42
+
43
+    /** {@inheritDoc} */
44
+    /*@Override
45
+    public void paint(final Graphics g, final JComponent c) {
46
+        if (c.isOpaque()) {
47
+            g.setColor(c.getBackground());
48
+            g.fillRect(0, 0, c.getWidth(), c.getHeight());
49
+        }
50
+        paint(g, c);
51
+    }*/
52
+
53
+    /** {@inheritDoc} */
54
+    /*@Override
55
+    public void update(final Graphics g, final JComponent c) {
56
+        if (c.isOpaque()) {
57
+            g.setColor(c.getBackground());
58
+            g.fillRect(0, 0, c.getWidth(), c.getHeight());
59
+        }
60
+        paint(g, c);
61
+    }*/
62
+
63
+    protected void paintTextPane(final Graphics2D g, final TextPane c) {
64
+    }
37 65
 }

+ 0
- 200
src/com/dmdirc/addons/ui_swing/textpane2/DocumentContent.java View File

@@ -1,200 +0,0 @@
1
-/*
2
- * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.ui_swing.textpane2;
24
-
25
-import java.util.HashMap;
26
-import java.util.LinkedList;
27
-import java.util.List;
28
-import java.util.Map;
29
-
30
-import javax.swing.text.AbstractDocument;
31
-import javax.swing.text.BadLocationException;
32
-import javax.swing.text.Position;
33
-import javax.swing.text.Segment;
34
-import javax.swing.undo.UndoableEdit;
35
-
36
-/**
37
- * An AbstractDocument.Content implementation that uses linked lists to enable
38
- * rapid addition of text to the end of the document.
39
- * 
40
- * @author chris
41
- */
42
-public class DocumentContent implements AbstractDocument.Content {
43
-
44
-    /**
45
-     * The number of characters we should index the offset after. Smaller numbers
46
-     * mean more memory usage and more CPU time when adding lines, but shorter
47
-     * lookup times. Larger numbers mean less memory usage and CPU time when
48
-     * adding, but longer lookup timesb.
49
-     */
50
-    private static final int OFFSET_INDEX = 5000;
51
-
52
-    /** The current end offset. */
53
-    private int endOffset = 0;
54
-
55
-    /**
56
-     * The data belonging to this content. Generally each entry will be a single
57
-     * line (ending in LF), but there is no reason why this always has to be the
58
-     * case.
59
-     */
60
-    private final List<String> data = new LinkedList<String>();
61
-
62
-    /** The end offset of each line. */
63
-    private final List<Integer> endOffsets = new LinkedList<Integer>();
64
-
65
-    /**
66
-     * A cache of offsets to their corresponding index in the data/endOffsets
67
-     * list. A key of n references the (n*OFFSET_INDEX)th character, and the
68
-     * corresponding value will reference the line where that character
69
-     * occurs, or the line immediately before it.
70
-     */
71
-    private final Map<Integer, Integer> offsetCache = new HashMap<Integer, Integer>();
72
-
73
-    /**
74
-     * Creates a new instance of DocumentContent.
75
-     */
76
-    public DocumentContent() {
77
-        try {
78
-            offsetCache.put(0, 0);
79
-
80
-            insertString(0, "");
81
-        } catch (BadLocationException ex) {
82
-            // Something's fucked. Oh well.
83
-        }
84
-    }
85
-
86
-    /** {@inheritDoc} */
87
-    @Override
88
-    public Position createPosition(final int offset) throws BadLocationException {
89
-        return new Position() {
90
-
91
-            private final int meo = endOffset;
92
-            private final boolean move = offset == endOffset + 1
93
-                    || (offset != 0 && offset == endOffset);
94
-
95
-            @Override
96
-            public int getOffset() {
97
-                int myOffset = move ? 
98
-                    ((offset != 0 && offset == meo) ? endOffset : endOffset + 1) : offset;
99
-                
100
-                return myOffset;
101
-            }
102
-        };
103
-    }
104
-
105
-    /** {@inheritDoc} */
106
-    @Override
107
-    public int length() {
108
-        return endOffset + 1; // The extra 1 is for our phantom LF
109
-    }
110
-
111
-    /** {@inheritDoc} */
112
-    @Override
113
-    public UndoableEdit insertString(final int where, final String str)
114
-            throws BadLocationException {
115
-        if (where == endOffset) {
116
-            int offset = endOffset / OFFSET_INDEX;
117
-            endOffset += str.length();
118
-
119
-            data.add(str);
120
-            endOffsets.add(endOffset);
121
-
122
-            while (endOffset / OFFSET_INDEX > offset) {
123
-                offsetCache.put(++offset, data.size() - 1);
124
-            }
125
-        } else {
126
-            throw new BadLocationException("Inserting strings at any offset" +
127
-                    " except the end of the document is not supported.", where);
128
-        }
129
-
130
-        return null;
131
-    }
132
-
133
-    /** {@inheritDoc} */
134
-    @Override
135
-    public UndoableEdit remove(final int where, final int nitems) throws BadLocationException {
136
-        throw new UnsupportedOperationException("Not supported.");
137
-    }
138
-
139
-    /** {@inheritDoc} */
140
-    @Override
141
-    public String getString(final int where, final int len) throws BadLocationException {
142
-        if (where + len > endOffset + 1 || where < 0 || len < 0) {
143
-            throw new BadLocationException("Invalid location/length",
144
-                    where < 0 ? where : where + len);
145
-        }
146
-
147
-        final StringBuilder res = new StringBuilder(len);
148
-        int offset = findOffset(where);
149
-        int loc = where;
150
-
151
-        do {
152
-            String part = data.get(offset);
153
-            
154
-            int start = endOffsets.get(offset) - part.length();
155
-            
156
-            if (offset == data.size() - 1) {
157
-                // Last line - add our phantom LF
158
-                part = part + "\n";
159
-                start++;
160
-            }
161
-
162
-            int beginning = Math.max(loc - start, 0);
163
-            int end = Math.min(part.length(), beginning + len - res.length());
164
-
165
-            if (beginning < part.length()) {
166
-                res.append(part.substring(beginning, end));
167
-            }
168
-
169
-            offset++;
170
-        } while (res.length() < len && offset < data.size());
171
-
172
-        return res.toString();
173
-    }
174
-
175
-    /**
176
-     * Looks up the offset of the specified location. Given a character index,
177
-     * returns the location of the specified character in the data list.
178
-     * 
179
-     * @param where The character index to lookup
180
-     * @return The location of the specified character in the data list
181
-     */
182
-    private int findOffset(final int where) {
183
-        int res = offsetCache.get(where / OFFSET_INDEX);
184
-
185
-        while (endOffsets.get(res) < where) {
186
-            res++;
187
-        }
188
-        
189
-        return res;
190
-    }
191
-
192
-    /** {@inheritDoc} */
193
-    @Override
194
-    public void getChars(final int where, final int len, final Segment txt)
195
-            throws BadLocationException {
196
-        txt.array = getString(where, len).toCharArray();
197
-        txt.offset = 0;
198
-        txt.count = txt.array.length;
199
-    }
200
-}

+ 0
- 48
src/com/dmdirc/addons/ui_swing/textpane2/DocumentContentTest.java View File

@@ -1,48 +0,0 @@
1
-package com.dmdirc.addons.ui_swing.textpane2;
2
-
3
-import java.awt.Dimension;
4
-import javax.swing.JFrame;
5
-import javax.swing.JScrollPane;
6
-import javax.swing.JTextPane;
7
-import javax.swing.text.BadLocationException;
8
-import javax.swing.text.StyleContext;
9
-
10
-public class DocumentContentTest {
11
-
12
-    public static void main(String[] args) throws BadLocationException {
13
-
14
-        final JFrame frame = new JFrame();
15
-        final JTextPane tp = new JTextPane();
16
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
17
-        frame.setPreferredSize(new Dimension(800, 600));
18
-        tp.setEditable(false);
19
-        tp.setDocument(new IRCDocument(new DocumentContent(), new StyleContext()));
20
-
21
-        frame.add(new JScrollPane(tp));
22
-
23
-        frame.pack();
24
-        
25
-        frame.setVisible(true);
26
-        
27
-        for (int i = 0; i <= 1000; i++) {
28
-        tp.getDocument().insertString(tp.getDocument().getLength(), "RAR.... RAR!!!! RARRRR\n", null);
29
-        Thread.yield();
30
-        }
31
-
32
-        try {
33
-            Thread.sleep(500);
34
-        } catch (InterruptedException ex) {
35
-            //Ignore
36
-        }
37
-        
38
-        tp.getDocument().insertString(tp.getDocument().getLength(), "RAR1\n", null);
39
-        
40
-        try {
41
-            Thread.sleep(500);
42
-        } catch (InterruptedException ex) {
43
-            //Ignore
44
-        }
45
-        
46
-        tp.getDocument().insertString(tp.getDocument().getLength(), "RAR2\n", null);
47
-    }
48
-}

+ 0
- 73
src/com/dmdirc/addons/ui_swing/textpane2/IRCDocument.java View File

@@ -1,73 +0,0 @@
1
-/*
2
- * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.ui_swing.textpane2;
24
-
25
-import javax.swing.text.BadLocationException;
26
-import javax.swing.text.DefaultStyledDocument;
27
-import javax.swing.text.Segment;
28
-import javax.swing.text.StyleContext;
29
-
30
-/** Stylised document. */
31
-public class IRCDocument extends DefaultStyledDocument {
32
-
33
-    /**
34
-     * A version number for this class. It should be changed whenever the class
35
-     * structure is changed (or anything else that would prevent serialized
36
-     * objects being unserialized with the new class).
37
-     */
38
-    private static final long serialVersionUID = 1;
39
-
40
-    /** Instantiates a new IRCDocument. */
41
-    public IRCDocument() {
42
-        this(new StyleContext());
43
-    }
44
-
45
-    /**
46
-     * Instantiates a new IRCDocument using the specified StyleContext.
47
-     *
48
-     * @param styles StyleContext to use
49
-     */
50
-    public IRCDocument(final StyleContext styles) {
51
-        super(new DocumentContent(), styles);
52
-    }
53
-
54
-    public IRCDocument(Content c, StyleContext styles) {
55
-        super(c, styles);
56
-    }
57
-    
58
-    public String getText(int offset, int length) throws BadLocationException {
59
-	if (length < 0) {
60
-	    throw new BadLocationException("Length must be positive. Length = "+length, 0);
61
-	}
62
-	
63
-	return super.getText(offset, length);
64
-    }    
65
-    
66
-    public void getText(int offset, int length, Segment txt) throws BadLocationException {
67
-	if (length < 0) {
68
-	    throw new BadLocationException("Length must be positive. Length = "+length, 0);
69
-	}
70
-	
71
-        super.getText(offset, length, txt);
72
-    }    
73
-}

+ 0
- 106
src/com/dmdirc/addons/ui_swing/textpane2/IRCTextPane.java View File

@@ -1,106 +0,0 @@
1
-/*
2
- * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.ui_swing.textpane2;
24
-
25
-import com.dmdirc.logger.ErrorLevel;
26
-import com.dmdirc.logger.Logger;
27
-
28
-import javax.swing.JTextPane;
29
-import javax.swing.text.BadLocationException;
30
-
31
-/** Text pane designed for IRC. */
32
-public class IRCTextPane extends JTextPane {
33
-
34
-    /**
35
-     * A version number for this class. It should be changed whenever the class
36
-     * structure is changed (or anything else that would prevent serialized
37
-     * objects being unserialized with the new class).
38
-     */
39
-    private static final long serialVersionUID = 1;
40
-
41
-    /** Instantiates a new IRCTextPane. */
42
-    public IRCTextPane() {
43
-        this(new IRCDocument());
44
-    }
45
-
46
-    /**
47
-     * Instantiates a new IRCTextPane with the specified document.
48
-     *
49
-     * @param doc
50
-     */
51
-    public IRCTextPane(final IRCDocument doc) {
52
-        super(doc);
53
-        super.setEditable(false);
54
-    }
55
-
56
-    /**
57
-     * Adds an array of unparsed styled strings to the textpane.
58
-     *
59
-     * @param strings Unstyled lines to add
60
-     */
61
-    public void addStyledString(final String[] strings) {
62
-        //Styliser.addStyledString((StyledDocument) getDocument(), string);
63
-        for (String str : strings) {
64
-            try {
65
-                getDocument().insertString(getDocument().getLength(), str, null);
66
-            } catch (BadLocationException ex) {
67
-                Logger.appError(ErrorLevel.HIGH, "Adding a line to the document failed.", ex);
68
-            }
69
-        }
70
-    }
71
-
72
-    /**
73
-     * Adds an unparsed styled string to the textpane.
74
-     *
75
-     * @param string Unstyled line to add
76
-     */
77
-    public void addStyledString(final String string) {
78
-        addStyledString(new String[]{string});
79
-    }
80
-
81
-    /** Clears the textpane. */
82
-    public void clear() {
83
-        setDocument(new IRCDocument());
84
-    }
85
-
86
-    /** Clears the selection in the textpane. */
87
-    public void clearSelection() {
88
-        setSelectionStart(0);
89
-        setSelectionEnd(0);
90
-    }
91
-
92
-    /**
93
-     * Trims the textpane to the specified size.
94
-     *
95
-     * @param frameBufferSize Size to trim the textpane to
96
-     */
97
-    public void trim(final int frameBufferSize) {
98
-        //trim
99
-    }
100
-
101
-    /** {@inheritDoc} */
102
-    @Override
103
-    public void setEditable(final boolean b) {
104
-        //Ignore
105
-    }
106
-}

+ 3
- 3
test/com/dmdirc/ui/messages/StyliserStylesTest.java View File

@@ -22,8 +22,8 @@
22 22
 
23 23
 package com.dmdirc.ui.messages;
24 24
 
25
+import com.dmdirc.addons.ui_swing.textpane.Line;
25 26
 import com.dmdirc.config.IdentityManager;
26
-import com.dmdirc.addons.ui_swing.textpane.TextPane;
27 27
 import java.awt.Color;
28 28
 import java.awt.font.TextAttribute;
29 29
 import java.text.AttributedCharacterIterator;
@@ -57,8 +57,8 @@ public class StyliserStylesTest {
57 57
         final DefaultStyledDocument doc = new DefaultStyledDocument();
58 58
         final StringBuilder builder = new StringBuilder();
59 59
         Styliser.addStyledString(doc, new String[]{input});
60
-        final AttributedCharacterIterator aci = 
61
-                TextPane.styledDocumentToAttributedString(doc).getIterator();        
60
+        final AttributedCharacterIterator aci = new Line(
61
+                new String[]{input, }).getStyled().getIterator();
62 62
          
63 63
         Map<AttributedCharacterIterator.Attribute, Object> map = null;
64 64
         char chr = aci.current();

+ 0
- 1
testing View File

@@ -1 +0,0 @@
1
-MoO1

Loading…
Cancel
Save