1 /*****************************************************/
2 /* This java file is a part of the */
4 /* - Plouf's Java IRC Client - */
6 /* Copyright (C) 2002 - 2005 Philippe Detournay */
8 /* All contacts : theplouf@yahoo.com */
10 /* PJIRC is free software; you can redistribute */
11 /* it and/or modify it under the terms of the GNU */
12 /* General Public License as published by the */
13 /* Free Software Foundation; version 2 or later of */
16 /* PJIRC is distributed in the hope that it will */
17 /* be useful, but WITHOUT ANY WARRANTY; without */
18 /* even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
20 /* General Public License for more details. */
22 /* You should have received a copy of the GNU */
23 /* General Public License along with PJIRC; if */
24 /* not, write to the Free Software Foundation, */
25 /* Inc., 59 Temple Place, Suite 330, Boston, */
26 /* MA 02111-1307 USA */
28 /*****************************************************/
32 import irc.IRCConfiguration;
33 import irc.ListenerGroup;
34 import irc.StyleContext;
36 import java.awt.Color;
37 import java.awt.Cursor;
39 import java.awt.Graphics;
40 import java.awt.Image;
41 import java.awt.Panel;
42 import java.awt.Rectangle;
43 import java.awt.event.InputEvent;
44 import java.awt.event.MouseEvent;
45 import java.awt.event.MouseListener;
46 import java.awt.event.MouseMotionListener;
47 import java.util.Enumeration;
48 import java.util.Hashtable;
49 import java.util.Vector;
52 * LimitedArray, used to remove too old lines from the text history.
58 private Object[] _array;
61 * Create a new LimitedArray
64 * maximum number of items.
66 public LimitedArray(int max) {
70 _array = new Object[4];
74 * Expand the actual number of stockable items.
76 public void expand() {
77 if (_array.length >= _maximum)
79 int ns = _array.length << 1;
80 Object[] n = new Object[ns];
81 System.arraycopy(_array, 0, n, 0, _array.length);
91 public void add(Object obj) {
92 if (size() >= _array.length)
94 if (size() >= _array.length)
96 _array[size() % _array.length] = obj;
101 * Get the object at given index.
105 * @return the object at index, or null if object has been removed.
107 public Object get(int index) {
108 if (index < _missing)
110 return _array[(index) % _array.length];
114 * Get the number of objects.
116 * @return number of objects.
134 public DrawResult result;
138 * A styled list is a panel designed for displaying lines of styled text, using
139 * special color and style codes, and smileys.
141 public class StyledList extends Panel implements MouseListener, MouseMotionListener, FormattedStringDrawerListener {
142 private LimitedArray _list;
143 private Hashtable _nickInfos;
144 private boolean _wrap;
149 private int _toScrollX;
150 private int _toScrollY;
151 private FormattedStringDrawer _drawer;
152 private Image _buffer;
153 private int _bufferWidth;
154 private int _bufferHeight;
155 private int _lastWidth;
156 private int _lastHeight;
157 private Hashtable _results;
158 private MultipleWordCatcher _catcher;
159 private WordListRecognizer _wordListRecognizer;
160 private IRCConfiguration _ircConfiguration;
162 private int _pressedX;
163 private int _pressedY;
164 private int _draggedX;
165 private int _draggedY;
166 private boolean _dragging;
167 private DrawResultItem _currentItem;
168 private DrawResultItem _currentFloatItem;
169 private DrawResultItem _currentHighLightItem;
170 private String _currentFloatText;
171 private String _copiedString;
172 private boolean _fullDraw;
174 private ListenerGroup _listeners;
176 private ResultPair[] _addedResults;
177 private int _addedCount;
179 private int _hdirection;
180 private int _vdirection;
181 private Color _colormale;
182 private Color _colorfemeale;
183 private Color _colorundef;
185 private Vector _updateItems;
186 private long _lastRefresh = System.currentTimeMillis();
188 private Image _backImage;
189 private int _backTiling;
191 private int _maximumSize;
192 private DecodedLine _emptyLine;
194 private final static int BOTTOM = FormattedStringDrawer.BOTTOM;
195 private final static int TOP = FormattedStringDrawer.TOP;
196 /** Left to right direction. */
197 public final static int LEFT = FormattedStringDrawer.LEFT;
198 /** Right to left direction. */
199 public final static int RIGHT = FormattedStringDrawer.RIGHT;
201 private final static boolean _doubleBuffer = true; // NON-BUFFERED DISPLAY NOT
205 * Create a new StyledList with automatic text wraping.
208 * global irc configuration.
212 public StyledList(IRCConfiguration config, StyleContext context) {
213 this(config, true, context);
217 * Create a new StyledList.
220 * global irc configuration.
222 * true if wrapping must occur, false otherwise.
226 public StyledList(IRCConfiguration config, boolean wrap, StyleContext context) {
227 this(config, wrap, context, Color.blue, Color.pink, Color.gray);
231 * Create a new StyledList.
234 * global irc configuration.
236 * true if wrapping must occur, false otherwise.
240 * male color for asl.
242 * femeale color for asl.
244 * undefined gender color for asl.
246 public StyledList(IRCConfiguration config, boolean wrap, StyleContext context, Color male, Color femeale, Color undef) {
249 _backTiling = IRCConfiguration.TILING_CENTER;
251 _colorfemeale = femeale;
253 _nickInfos = new Hashtable();
255 _addedResults = new ResultPair[64];
256 for (int i = 0; i < _addedResults.length; i++)
257 _addedResults[i] = new ResultPair();
260 _vdirection = BOTTOM;
261 _ircConfiguration = config;
264 _currentFloatItem = null;
265 _currentFloatText = null;
272 _drawer = new FormattedStringDrawer(_ircConfiguration, context, this);
273 _drawer.setHorizontalDirection(_hdirection);
274 _drawer.setVerticalDirection(_vdirection);
275 _catcher = new MultipleWordCatcher();
276 _wordListRecognizer = new WordListRecognizer();
277 _catcher.addRecognizer(new ChannelRecognizer());
278 _catcher.addRecognizer(new URLRecognizer());
279 _catcher.addRecognizer(_wordListRecognizer);
280 _results = new Hashtable();
281 _listeners = new ListenerGroup();
282 addMouseListener(this);
283 addMouseMotionListener(this);
284 _maximumSize = _ircConfiguration.getI("style:maximumlinecount");
285 _emptyLine = _drawer.decodeLine("");
287 setBackgroundImage(_ircConfiguration.getStyleBackgroundImage(context));
288 setBackgroundTiling(_ircConfiguration.getStyleBackgroundTiling(context));
289 if (_ircConfiguration.getB("style:righttoleft"))
290 setHorizontalDirection(RIGHT);
294 * Release this object. No further call may be performed on this object.
296 public void release() {
299 removeMouseListener(this);
300 removeMouseMotionListener(this);
303 private void drawBackImage(Graphics g, int w, int h) {
304 int iw = _backImage.getWidth(this);
305 int ih = _backImage.getHeight(this);
306 switch (_backTiling & 0xff) {
307 case IRCConfiguration.TILING_FIXED: {
310 if ((_backTiling & IRCConfiguration.TILING_HORIZONTAL_RIGHT) != 0)
312 if ((_backTiling & IRCConfiguration.TILING_VERTICAL_DOWN) != 0)
314 g.setColor(_drawer.getColor(0));
315 g.fillRect(0, 0, w, h);
316 g.drawImage(_backImage, x, y, _drawer.getColor(0), this);
319 case IRCConfiguration.TILING_CENTER: {
320 int x = (w - iw) / 2;
321 int y = (h - ih) / 2;
322 g.setColor(_drawer.getColor(0));
323 g.fillRect(0, 0, w, h);
324 g.drawImage(_backImage, x, y, _drawer.getColor(0), this);
327 case IRCConfiguration.TILING_STRETCH: {
328 g.drawImage(_backImage, 0, 0, w, h, _drawer.getColor(0), this);
331 case IRCConfiguration.TILING_TILE: {
336 g.drawImage(_backImage, x, y, _drawer.getColor(0), this);
346 private void expandResult() {
347 ResultPair[] n = new ResultPair[_addedResults.length * 2];
348 System.arraycopy(_addedResults, 0, n, 0, _addedResults.length);
349 for (int i = _addedResults.length; i < n.length; i++)
350 n[i] = new ResultPair();
355 * Set the horizontal display direction.
358 * horizontal display direction.
360 public void setHorizontalDirection(int direction) {
361 _hdirection = direction;
362 _drawer.setHorizontalDirection(_hdirection);
366 * Get the horizontal display direction.
368 * @return horizontal display direction.
370 public int getHorizontalDirection() {
375 * Set the background image for display.
378 * background image, or null if no background image is to be
381 public void setBackgroundImage(Image img) {
387 * Set the background image tiling.
390 * background image tiling mode. See IRCConfiguration for tiling
393 public void setBackgroundTiling(int t) {
399 * Set the font to be used for display.
405 public void setFont(Font fnt) {
406 _drawer.setFont(fnt);
415 * mode, true if end-of-line wrapping must be performed, false
418 public void setWrap(boolean wrap) {
425 * Set the nick list for recognition.
430 public synchronized void setNickList(String[] list) {
431 String[] actualList = new String[list.length];
433 for (int i = 0; i < list.length; i++) {
434 String nick = list[i];
436 int pos = nick.indexOf(":");
438 info = nick.substring(pos + 1);
439 nick = nick.substring(0, pos);
441 actualList[i] = nick;
442 _nickInfos.put(nick.toLowerCase(java.util.Locale.ENGLISH), info);
444 _wordListRecognizer.setList(actualList);
453 public synchronized void addStyledListListener(StyledListListener lis) {
454 _listeners.addListener(lis);
461 * the listener to remove.
463 public synchronized void removeStyledListListener(StyledListListener lis) {
464 _listeners.removeListener(lis);
468 * Set the left offset for this list rendering.
471 * the left offset, in pixel.
473 public synchronized void setLeft(int left) {
474 // int w=getSize().width;
479 if (_left >= getLogicalWidth())
480 _left = getLogicalWidth() - 1;
482 if (_hdirection == RIGHT)
485 if (_left != oldLeft) {
486 addToScroll(_left - oldLeft, 0);
492 * Get the left offset.
494 * @return the left offset, in pixel.
496 public int getLeft() {
497 if (_hdirection == RIGHT)
503 * Set the first line to be displayed.
506 * the first line to be displayed.
508 public synchronized void setFirst(int first) {
509 if (_vdirection != TOP)
512 _drawer.setVerticalDirection(TOP);
513 int oldFirst = _first;
517 if (_first >= _list.size())
518 _last = _list.size() - 1;
519 if (_first != oldFirst) {
520 addToScroll(0, _first - oldFirst);
526 * Set the last line to be displayed.
529 * last line to be displayed.
531 public synchronized void setLast(int last) {
532 if (_vdirection != BOTTOM)
534 _vdirection = BOTTOM;
535 _drawer.setVerticalDirection(BOTTOM);
540 if (_last >= _list.size())
541 _last = _list.size() - 1;
542 if (_last != oldLast) {
543 addToScroll(0, _last - oldLast);
549 * Get the logical width of this list.
551 * @return the logical width, in pixel.
553 public int getLogicalWidth() {
558 * Get the last displayed line.
560 * @return the last displayed line.
562 public int getLast() {
567 * Get the number of line in this list.
569 * @return the line count.
571 public synchronized int getLineCount() {
576 * Add a line at the end of this list.
581 public synchronized void addLine(String line) {
582 DecodedLine dline = _drawer.decodeLine(line);
585 if (_vdirection == BOTTOM) {
586 if (_last == _list.size() - 2)
588 } else if (_vdirection == TOP) {
595 * Add the given lines at the end of this list.
600 public synchronized void addLines(String[] lines) {
601 boolean willScroll = (_list.size() - 1 == _last);
603 for (int i = 0; i < lines.length; i++)
604 _list.add(_drawer.decodeLine(lines[i]));
606 if (_vdirection == BOTTOM) {
608 setLast(_list.size() - 1);
609 } else if (_vdirection == TOP) {
615 private void reinit() {
619 _results = new Hashtable();
623 * Dispose any off-screen ressources used by the list. This method won't put
624 * the list in a non-drawable state, but next screen refresh might me slower.
626 public synchronized void dispose() {
631 * Clear all the lines in this list.
633 public synchronized void clear() {
634 _list = new LimitedArray(_maximumSize);
635 _last = _list.size() - 1;
638 _width = getSize().width;
644 * Clear all the lines in this list, reconfiguring the maximum line count to
648 * the new maximum line count.
650 public synchronized void clear(int max) {
655 private void drawPart(Graphics g, int x, int y, int w, int h, boolean analyse, int gw, int gh) {
656 // System.out.println("draw part "+x+","+y+","+w+","+h);
662 if (_backImage != null) {
663 drawBackImage(g, gw, gh);
665 g.setColor(_drawer.getColor(0));
666 g.fillRect(x, y, w, h);
669 if (_vdirection == BOTTOM) {
671 int posY = getSize().height;
672 while ((posY > y + h) && (first >= 0))
673 posY -= getHeight(first--, g);
675 posY += getHeight(++first, g);
676 draw(g, 0, first, posY, y, x, x + w - 1, analyse);
677 } else if (_vdirection == TOP) {
680 while ((posY < y) && (first < _list.size()))
681 posY += getHeight(first++, g);
683 posY -= getHeight(--first, g);
684 draw(g, first, _list.size() - 1, posY, y + h, x, x + w - 1, analyse);
689 public synchronized void paint(Graphics g) {
690 if (_doubleBuffer || (_toScrollX != 0) || (_toScrollY != 0)) {
691 if ((_toScrollX != 0) || (_toScrollY != 0))
698 int w = getSize().width;
699 int h = getSize().height;
700 Rectangle cl = g.getClipBounds();
707 drawPart(g, x, y, w, h, false, w, h);
710 private int getHeight(Graphics g, int a, int b) {
717 for (int i = a; i <= b; i++)
718 res += getHeight(i, g);
722 private void draw(Graphics g, int from, int to, int y, int crossy, int debx, int finx, boolean analyse) {
723 int w = getSize().width;
724 // int h=getSize().height;
728 DrawResult res = new DrawResult();
730 if (_vdirection == BOTTOM) {
732 while ((index >= from) && (y > crossy)) {
733 DecodedLine str = (DecodedLine) _list.get(index);
736 _drawer.draw(str, g, -_left, w - 1 - _left, y, debx, finx, analyse, _wrap, res);
737 StyledRectangle rect = res.rectangle;
738 if (rect.width > _width) {
740 _listeners.sendEventAsync("virtualSizeChanged", this);
743 ResultPair p = _addedResults[_addedCount++];
744 if (_addedCount == _addedResults.length)
748 res = new DrawResult();
755 while ((index <= to) && (y < crossy)) {
756 DecodedLine str = (DecodedLine) _list.get(index);
759 _drawer.draw(str, g, -_left, w - 1 - _left, y, debx, finx, analyse, _wrap, res);
760 StyledRectangle rect = res.rectangle;
761 if (rect.width > _width) {
763 _listeners.sendEventAsync("virtualSizeChanged", this);
766 ResultPair p = _addedResults[_addedCount++];
767 if (_addedCount == _addedResults.length)
771 res = new DrawResult();
780 private void addToScroll(int vx, int vy) {
785 private int getScrollX() {
788 int res = _toScrollX;
793 private int getScrollY() {
796 int res = _toScrollY;
801 private void scrollDrawItems(int dx, int dy) {
802 int h = getSize().height;
803 Enumeration e = _results.keys();
804 while (e.hasMoreElements()) {
805 Integer key = (Integer) e.nextElement();
806 DrawResult res = (DrawResult) _results.get(key);
807 res.rectangle.x += dx;
808 res.rectangle.y += dy;
809 if ((res.rectangle.y + res.rectangle.height < 0) || (res.rectangle.y >= h)) {
810 _results.remove(key);
815 private void combineItems() {
816 for (int i = 0; i < _addedCount; i++) {
817 ResultPair k = _addedResults[i];
818 _results.put(new Integer(k.line), k.result);
823 private DrawResultItem findItem(int x, int y) {
824 Enumeration e = _results.elements();
825 while (e.hasMoreElements()) {
826 DrawResult result = (DrawResult) e.nextElement();
827 if (result.rectangle.contains(x, y)) {
828 int rx = x - result.rectangle.x;
829 int ry = y - result.rectangle.y;
830 for (int i = 0; i < result.items.length; i++) {
831 DrawResultItem item = result.items[i];
832 if (item.rectangle.contains(rx, ry))
840 private int findLine(int y) {
841 Enumeration e = _results.keys();
842 while (e.hasMoreElements()) {
843 Integer i = (Integer) e.nextElement();
845 DrawResult result = (DrawResult) _results.get(i);
846 if ((result.rectangle.y <= y) && (result.rectangle.y + result.rectangle.height > y)) {
853 private int getHeight(int lineIndex, Graphics g) {
854 DrawResult r = (DrawResult) _results.get(new Integer(lineIndex));
856 return r.rectangle.height;
858 int wrapPos = getSize().width;
859 DecodedLine str = (DecodedLine) _list.get(lineIndex);
862 return _drawer.getHeight(str, g, -_left, wrapPos, _wrap);
865 private Color findColor(String info) {
866 return _ircConfiguration.getASLColor(info, _colormale, _colorfemeale, _colorundef);
869 private synchronized Vector getUpdateItems() {
870 Vector items = _updateItems;
875 private synchronized boolean addToUpdateItems(Integer line) {
876 if (_updateItems == null)
877 _updateItems = new Vector();
878 for (int i = 0; i < _updateItems.size(); i++) {
879 Integer r = (Integer) _updateItems.elementAt(i);
883 _updateItems.insertElementAt(line, _updateItems.size());
888 public synchronized void update(Graphics g) {
889 int w = getSize().width;
890 int h = getSize().height;
891 if (h <= 0 || w <= 0)
896 if (_buffer != null) {
897 if ((_bufferWidth < w) || (_bufferHeight < h)) {
900 // Optimize memory usage
901 if ((_bufferHeight > w * 1.5) || (_bufferHeight > h * 1.5)) {
904 if ((_lastWidth != w) || (_lastHeight != h)) {
912 if (_buffer == null) {
913 _buffer = createImage(w, h);
914 if (_buffer == null) {
923 gra = _buffer.getGraphics();
926 if (_ircConfiguration.getB("style:backgroundimage"))
929 int scrx = getScrollX();
930 int scry = getScrollY();
931 Vector items = getUpdateItems();
936 gra.copyArea(0, 0, w + scrx, h, -scrx, 0);
937 scrollDrawItems(-scrx, 0);
938 drawPart(gra, 0, 0, -scrx, h, false, w, h);
939 } else if (scrx > 0) {
940 gra.copyArea(scrx, 0, w - scrx, h, -scrx, 0);
941 scrollDrawItems(-scrx, 0);
942 drawPart(gra, w - scrx, 0, scrx, h, false, w, h);
947 if (_vdirection == BOTTOM)
948 baseY = getHeight(gra, _last - scry + 1, _last);
950 baseY = getHeight(gra, _first - scry, _first - 1);
952 gra.copyArea(0, baseY, w, h - baseY, 0, -baseY);
953 scrollDrawItems(0, -baseY);
954 drawPart(gra, 0, h - baseY, w, baseY, true, w, h);
956 } else if (scry < 0) {
958 if (_vdirection == BOTTOM)
959 baseY = getHeight(gra, _last + 1, _last - scry);
961 baseY = getHeight(gra, _first, _first - scry - 1);
963 gra.copyArea(0, 0, w, h - baseY, 0, baseY);
964 scrollDrawItems(0, baseY);
965 drawPart(gra, 0, 0, w, baseY, true, w, h);
970 for (int i = 0; i < items.size(); i++) {
971 Integer line = (Integer) items.elementAt(i);
972 DrawResult res = (DrawResult) _results.get(line);
974 StyledRectangle r = res.rectangle;
975 drawPart(gra, r.x, r.y, r.width, r.height, false, w, h);
981 _results = new Hashtable();
982 drawPart(gra, 0, 0, w, h, true, w, h);
990 g.drawImage(_buffer, 0, 0, this);
994 if (!_dragging && (_currentFloatItem != null) && _ircConfiguration.getB("style:floatingasl")) {
995 int x = _currentFloatItem.rectangle.x + _currentFloatItem.parent.rectangle.x + 4;
996 int y = _currentFloatItem.rectangle.y + _currentFloatItem.parent.rectangle.y;
997 if (_vdirection == TOP)
1005 String info = _currentFloatText;
1006 String text = _ircConfiguration.formatASL(info);
1007 if (text.length() > 0) {
1008 int tw = g.getFontMetrics().stringWidth(text);
1009 int fh = g.getFont().getSize();
1015 g.setColor(getAlphaColor(findColor(info), _ircConfiguration.getI("style:floatingaslalpha")));
1016 g.fillRect(x, y, tw + 4, fh + 4);
1017 g.setColor(Color.white);
1018 g.drawString(text, x + 2, y + fh);
1022 if (_ircConfiguration.getB("style:highlightlinks")) {
1023 if (!_dragging && (_currentHighLightItem != null)) {
1024 int x = _currentHighLightItem.rectangle.x + _currentHighLightItem.parent.rectangle.x;
1025 int y = _currentHighLightItem.rectangle.y + _currentHighLightItem.parent.rectangle.y;
1026 g.setXORMode(Color.white);
1027 g.setColor(Color.black);
1028 g.fillRect(x, y, _currentHighLightItem.rectangle.width, _currentHighLightItem.rectangle.height);
1034 private Color getAlphaColor(Color c, int alpha) {
1036 return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
1037 } catch (Throwable ex) {
1042 private void makeXor(Graphics g) {
1044 int dw = _draggedX - _pressedX;
1045 int dh = _draggedY - _pressedY;
1047 int pressedX = _pressedX;
1048 int pressedY = _pressedY;
1050 g.setXORMode(Color.white);
1051 g.setColor(Color.black);
1052 int i = findLine(pressedY);
1054 DrawResult result = (DrawResult) _results.get(new Integer(i));
1056 if (result == null) {
1063 px = pressedX - result.rectangle.x;
1064 py = pressedY - result.rectangle.y;
1066 DrawResultItem item = null;
1068 for (a = 0; a < result.items.length; a++) {
1069 if (result.items[a].rectangle.contains(px, py)) {
1070 item = result.items[a];
1075 if ((item == null) || ((px + dw < item.rectangle.x) && (py + dh < item.rectangle.y))
1076 || (py + dh < item.rectangle.y)) {
1080 boolean terminated = false;
1081 while (!terminated) {
1082 res += item.originalstrippedword;
1083 StyledRectangle r = item.rectangle;
1084 g.fillRect(r.x + result.rectangle.x, r.y + result.rectangle.y, r.width, r.height);
1086 if (!((i == basei) && (a == b)) && (item.rectangle.contains(px + dw, py + dh)))
1089 if (b >= result.items.length) {
1092 result = (DrawResult) _results.get(new Integer(i));
1095 px = pressedX - result.rectangle.x;
1096 py = pressedY - result.rectangle.y;
1099 item = result.items[b];
1100 if (item.rectangle.y > py + dh)
1102 if (_hdirection == LEFT)
1103 if ((item.rectangle.x > px + dw) && (item.rectangle.y + item.rectangle.height > py + dh))
1105 if (_hdirection == RIGHT)
1106 if ((item.rectangle.x + item.rectangle.width < px + dw) && (item.rectangle.y + item.rectangle.height > py + dh))
1110 _copiedString = res;
1115 public synchronized void mouseClicked(MouseEvent e) {
1116 if ((e.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
1118 for (int i = 0; i < _list.size(); i++) {
1119 DecodedLine str = (DecodedLine) _list.get(i);
1122 res += str.original + "\n";
1124 _listeners.sendEventAsync("copyEvent", this, res, e);
1129 public void mouseEntered(MouseEvent e) {
1130 _currentFloatItem = null;
1131 _currentItem = null;
1132 _currentHighLightItem = null;
1138 public void mouseExited(MouseEvent e) {
1139 _currentFloatItem = null;
1140 _currentItem = null;
1141 _currentHighLightItem = null;
1146 public synchronized void mousePressed(MouseEvent e) {
1147 _pressedX = e.getX();
1148 _pressedY = e.getY();
1149 _draggedX = _pressedX;
1150 _draggedY = _pressedY;
1153 _currentItem = null;
1154 DrawResultItem item = findItem(e.getX(), e.getY());
1156 String type = _catcher.getType(item.item);
1159 } else if (type.equals("channel")) {
1160 _listeners.sendEventAsync("channelEvent", this, item.item, e);
1161 } else if (type.equals("url")) {
1162 _listeners.sendEventAsync("URLEvent", this, item.item, e);
1163 } else if (type.equals("wordlist")) {
1164 _listeners.sendEventAsync("nickEvent", this, item.item, e);
1170 public synchronized void mouseReleased(MouseEvent e) {
1174 if (_copiedString.length() > 0)
1175 _listeners.sendEventAsync("copyEvent", this, _copiedString, e);
1180 public synchronized void mouseDragged(MouseEvent e) {
1181 _draggedX = e.getX();
1182 _draggedY = e.getY();
1184 DrawResultItem item = findItem(e.getX(), e.getY());
1185 if (item != _currentItem) {
1186 _currentItem = item;
1191 private void handCursor() {
1192 if (!getCursor().equals(new Cursor(Cursor.HAND_CURSOR)))
1193 setCursor(new Cursor(Cursor.HAND_CURSOR));
1196 private void defCursor() {
1197 if (!getCursor().equals(new Cursor(Cursor.DEFAULT_CURSOR)))
1198 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
1201 private boolean sameItem(DrawResultItem a, DrawResultItem b) {
1202 if ((a == null) && (b == null))
1212 public synchronized void mouseMoved(MouseEvent e) {
1213 DrawResultItem item = findItem(e.getX(), e.getY());
1214 DrawResultItem oldFloat = _currentFloatItem;
1215 DrawResultItem oldHigh = _currentHighLightItem;
1216 if (!sameItem(item, _currentItem)) {
1217 _currentItem = item;
1218 _currentFloatItem = null;
1219 _currentHighLightItem = null;
1221 String type = _catcher.getType(item.item);
1224 if (type.equals("wordlist")) {
1225 String info = (String) _nickInfos.get(item.item.toLowerCase(java.util.Locale.ENGLISH));
1228 if (info.length() == 0) {
1229 _currentFloatItem = null;
1231 _currentFloatItem = item;
1232 _currentFloatText = info;
1236 if (_currentFloatItem == null)
1237 _currentHighLightItem = item;
1244 boolean repaint = false;
1245 if (!sameItem(oldFloat, _currentFloatItem))
1246 if (_ircConfiguration.getB("style:floatingasl"))
1248 if (!sameItem(oldHigh, _currentHighLightItem))
1255 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
1256 // the background image has been updated
1263 public synchronized Boolean displayUpdated(Object handle, Integer what) {
1264 boolean foundSome = false;
1266 // now we should go through all our draw results, and find which of them
1267 // belong to this handle.
1268 Enumeration e = _results.keys();
1269 while (e.hasMoreElements()) {
1270 Integer line = (Integer) e.nextElement();
1271 DrawResult result = (DrawResult) _results.get(line);
1272 if (result.updateHandles != null) {
1273 for (int i = 0; i < result.updateHandles.size(); i++) {
1274 if (result.updateHandles.elementAt(i).equals(handle)) {
1275 if ((what.intValue() & FormattedStringDrawerListener.SIZE) != 0) {
1278 return Boolean.TRUE;
1281 // ok, so the line number 'line' must be redrawn
1284 // invalidate line line
1285 addToUpdateItems(line);
1286 if ((System.currentTimeMillis() - _lastRefresh > 10)
1287 || ((what.intValue() & FormattedStringDrawerListener.DATA) != 0)) {
1289 _lastRefresh = System.currentTimeMillis();
1297 return Boolean.TRUE;
1298 return Boolean.FALSE;