1 /*****************************************************/
\r
2 /* This java file is a part of the */
\r
4 /* - Plouf's Java IRC Client - */
\r
6 /* Copyright (C) 2002 - 2004 Philippe Detournay */
\r
8 /* All contacts : theplouf@yahoo.com */
\r
10 /* PJIRC is free software; you can redistribute */
\r
11 /* it and/or modify it under the terms of the GNU */
\r
12 /* General Public License as published by the */
\r
13 /* Free Software Foundation; version 2 or later of */
\r
16 /* PJIRC is distributed in the hope that it will */
\r
17 /* be useful, but WITHOUT ANY WARRANTY; without */
\r
18 /* even the implied warranty of MERCHANTABILITY or */
\r
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
\r
20 /* General Public License for more details. */
\r
22 /* You should have received a copy of the GNU */
\r
23 /* General Public License along with PJIRC; if */
\r
24 /* not, write to the Free Software Foundation, */
\r
25 /* Inc., 59 Temple Place, Suite 330, Boston, */
\r
26 /* MA 02111-1307 USA */
\r
28 /*****************************************************/
\r
30 package irc.gui.pixx;
\r
32 import irc.AudioConfiguration;
\r
33 import irc.EventDispatcher;
\r
34 import irc.IRCConfiguration;
\r
35 import irc.IRCTextProvider;
\r
36 import irc.ListenerGroup;
\r
38 import irc.SourceListener;
\r
39 import irc.StringParser;
\r
40 import irc.StyleContext;
\r
41 import irc.gui.GUISource;
\r
42 import irc.gui.common.AWTIrcTextField;
\r
43 import irc.gui.common.MouseWheelPanelListener;
\r
44 import irc.gui.common.MouseWheelPanelWrapper;
\r
45 import irc.style.FormattedStringDrawer;
\r
46 import irc.style.StyledList;
\r
47 import irc.style.StyledListListener;
\r
49 import java.awt.BorderLayout;
\r
50 import java.awt.Color;
\r
51 import java.awt.Dimension;
\r
52 import java.awt.Font;
\r
53 import java.awt.Frame;
\r
54 import java.awt.GridLayout;
\r
55 import java.awt.Panel;
\r
56 import java.awt.TextArea;
\r
57 import java.awt.event.ActionEvent;
\r
58 import java.awt.event.ActionListener;
\r
59 import java.awt.event.FocusEvent;
\r
60 import java.awt.event.FocusListener;
\r
61 import java.awt.event.MouseEvent;
\r
62 import java.awt.event.WindowEvent;
\r
63 import java.awt.event.WindowListener;
\r
64 import java.util.Calendar;
\r
65 import java.util.Enumeration;
\r
66 import java.util.Locale;
\r
71 public class BaseAWTSource extends Panel implements GUISource, SourceListener, ActionListener, PixxScrollBarListener,
\r
72 FocusListener, StyledListListener, WindowListener, MouseWheelPanelListener, AWTStyleSelectorExListener {
\r
76 protected Source _source;
\r
78 * Vertical scrollbar.
\r
80 protected PixxVerticalScrollBar _scroll;
\r
84 protected Panel _panel;
\r
88 protected StyledList _list;
\r
92 protected AWTIrcTextField _textField;
\r
94 * Used to display the title bar.
\r
96 protected FormattedStringDrawer _styler;
\r
100 protected String _title;
\r
102 * Stripped title string.
\r
104 protected String _strippedTitle;
\r
105 private ListenerGroup _listeners;
\r
107 * Pixx configuration.
\r
109 protected PixxConfiguration _pixxConfiguration;
\r
113 protected AWTStyleSelectorEx _selector;
\r
115 * Overall alignment.
\r
117 protected boolean _topToBottom;
\r
118 private MouseWheelPanelWrapper _wrapper;
\r
119 private String _nickPrefix;
\r
120 private String _nickPostfix;
\r
123 * Create a new AWTSource.
\r
126 * the global configuration.
\r
128 * the source of this awt source.
\r
130 public BaseAWTSource(PixxConfiguration config, Source source) {
\r
131 this(config, source, false);
\r
135 * Create a new AWTSource.
\r
138 * the global configuration.
\r
140 * the source of this awt source.
\r
141 * @param topToBottom
\r
142 * true if the display should be performed from top to bottom instead
\r
143 * of bottom to top.
\r
145 public BaseAWTSource(PixxConfiguration config, Source source, boolean topToBottom) {
\r
146 _topToBottom = topToBottom;
\r
147 _pixxConfiguration = config;
\r
148 _listeners = new ListenerGroup();
\r
150 addFocusListener(this);
\r
151 _source.addSourceListener(this);
\r
152 _panel = new Panel();
\r
153 _panel.addFocusListener(this);
\r
154 _panel.setBackground(Color.white);
\r
155 _scroll = new PixxVerticalScrollBar(_pixxConfiguration, 0, 0, 0.1);
\r
156 _scroll.addPixxScrollBarListener(this);
\r
157 setLayout(new BorderLayout());
\r
159 IRCConfiguration ircConfiguration = _pixxConfiguration.getIRCConfiguration();
\r
161 Color aslMale = _pixxConfiguration.getColor(PixxColorModel.COLOR_MALE);
\r
162 Color aslFemeale = _pixxConfiguration.getColor(PixxColorModel.COLOR_FEMEALE);
\r
163 Color aslUndef = _pixxConfiguration.getColor(PixxColorModel.COLOR_UNDEF);
\r
164 _list = new StyledList(ircConfiguration, true,
\r
165 ircConfiguration.getStyleContext(source.getType(), source.getName()), aslMale, aslFemeale, aslUndef);
\r
167 _list.addFocusListener(this);
\r
168 _list.addStyledListListener(this);
\r
169 _styler = new FormattedStringDrawer(ircConfiguration, getStyleContext());
\r
170 _textField = new AWTIrcTextField();
\r
172 boolean b = _pixxConfiguration.getB("displayentertexthere");
\r
174 _textField.setEnterTextHere(true, getText(PixxTextProvider.GUI_ENTER_TEXT_HERE));
\r
176 Color[] c = ircConfiguration.getStyleColors(getStyleContext());
\r
177 _textField.setBackground(c[0]);
\r
178 _textField.setForeground(c[1]);
\r
179 _textField.addFocusListener(this);
\r
180 Panel p = new Panel();
\r
181 p.setLayout(new BorderLayout());
\r
183 _wrapper = new MouseWheelPanelWrapper(_panel);
\r
184 _wrapper.addMouseWheelPanelListener(this);
\r
185 p.add(_wrapper, BorderLayout.CENTER);
\r
187 p.add(new PixxSeparator(PixxSeparator.BORDER_LEFT), BorderLayout.WEST);
\r
188 p.add(new PixxSeparator(PixxSeparator.BORDER_RIGHT), BorderLayout.EAST);
\r
189 p.add(new PixxSeparator(PixxSeparator.BORDER_UP), BorderLayout.NORTH);
\r
190 p.add(new PixxSeparator(PixxSeparator.BORDER_DOWN), BorderLayout.SOUTH);
\r
192 add(p, BorderLayout.CENTER);
\r
193 _panel.setLayout(new BorderLayout());
\r
194 _panel.add(_scroll, BorderLayout.EAST);
\r
195 _selector = new AWTStyleSelectorEx(_pixxConfiguration);
\r
196 _selector.setStyleContext(getStyleContext());
\r
197 _selector.addAWTStyleSelectorExListener(this);
\r
198 if (_pixxConfiguration.getB("styleselector")) {
\r
199 p = new Panel(new BorderLayout());
\r
200 p.add(_textField, BorderLayout.CENTER);
\r
201 p.add(_selector, BorderLayout.EAST);
\r
202 add(p, BorderLayout.SOUTH);
\r
204 add(_textField, BorderLayout.SOUTH);
\r
212 _textField.addActionListener(this);
\r
213 setTitle(_source.getName());
\r
214 _panel.add(_list, BorderLayout.CENTER);
\r
216 _nickPrefix = reformat(_pixxConfiguration.getS("nickprefix"));
\r
217 _nickPostfix = reformat(_pixxConfiguration.getS("nickpostfix"));
\r
220 private String reformat(String string) {
\r
222 for (int i = 0; i < string.length(); i++) {
\r
223 char c = string.charAt(i);
\r
225 if (i != string.length() - 1) {
\r
227 c = string.charAt(i);
\r
248 * Release this object. No further call may be performed on this object.
\r
250 public void release() {
\r
251 _wrapper.removeMouseWheelPanelListener(this);
\r
252 _source.removeSourceListener(this);
\r
253 _panel.removeFocusListener(this);
\r
254 _scroll.removePixxScrollBarListener(this);
\r
256 _list.removeFocusListener(this);
\r
257 _list.removeStyledListListener(this);
\r
258 _textField.removeFocusListener(this);
\r
259 _selector.removeAWTStyleSelectorExListener(this);
\r
260 _selector.release();
\r
261 _textField.removeActionListener(this);
\r
262 _textField.release();
\r
269 * Change the front color of the style selector.
\r
272 * the new front color.
\r
274 public void setFrontColor(int color) {
\r
275 _selector.getStyleSelector().setFrontColor(color);
\r
279 * Change the background color of the style selector.
\r
282 * the new background color.
\r
284 public void setBackColor(int color) {
\r
285 _selector.getStyleSelector().setBackColor(color);
\r
289 * Set the new bold status.
\r
292 * the new bold status.
\r
294 public void setBold(boolean bold) {
\r
295 _selector.getStyleSelector().setBold(bold);
\r
299 * Set the new underline status.
\r
302 * the new underline statu.
\r
304 public void setUnderline(boolean underline) {
\r
305 _selector.getStyleSelector().setUnderline(underline);
\r
309 public Dimension getPreferredSize() {
\r
310 return new Dimension(600, 300);
\r
314 * Set the current textfield text.
\r
317 * new textfield text.
\r
320 public void setFieldText(String txt) {
\r
321 _textField.setText(txt);
\r
322 _textField.setCaretPosition(txt.length());
\r
326 * Get the current textfield text.
\r
328 * @return the current textfield text.
\r
331 public String getFieldText() {
\r
332 return _textField.getText();
\r
336 * Validate the current textfield text, as if user pressed return key.
\r
339 public void validateText() {
\r
340 _textField.validateText();
\r
344 * Get style context for this awt source.
\r
346 * @return style context for this awt source.
\r
348 public StyleContext getStyleContext() {
\r
349 return _pixxConfiguration.getIRCConfiguration().getStyleContext(_source.getType(), _source.getName());
\r
353 * Get formatted text associated with the given text code, with no parameter.
\r
357 * @return formatted text.
\r
359 public String getText(int code) {
\r
360 return _pixxConfiguration.getText(code);
\r
364 * Get formatted text associated with the given text code, with one parameter.
\r
370 * @return formatted text.
\r
372 public String getText(int code, String p1) {
\r
373 return _pixxConfiguration.getText(code, p1);
\r
377 * Get formatted text associated with the given text code, with two
\r
385 * second parameter.
\r
386 * @return formatted text.
\r
388 public String getText(int code, String p1, String p2) {
\r
389 return _pixxConfiguration.getText(code, p1, p2);
\r
393 * Get formatted text associated with the given text code, with three
\r
401 * second parameter.
\r
404 * @return formatted text.
\r
406 public String getText(int code, String p1, String p2, String p3) {
\r
407 return _pixxConfiguration.getText(code, p1, p2, p3);
\r
414 * the listener to add.
\r
416 public void addBaseAWTSourceListener(BaseAWTSourceListener lis) {
\r
417 _listeners.addListener(lis);
\r
424 * the listener to remove.
\r
426 public void removeBaseAWTSourceListener(BaseAWTSourceListener lis) {
\r
427 _listeners.removeListener(lis);
\r
431 * Set this source title.
\r
434 * the source title.
\r
436 public void setTitle(String title) {
\r
437 if (title.equals(_title))
\r
440 _strippedTitle = _styler.getStripped(title);
\r
441 _listeners.sendEvent("titleChanged", this);
\r
445 * Get the stripped title.
\r
447 * @return the stripped title.
\r
449 public String getStrippedTitle() {
\r
450 return _strippedTitle;
\r
456 * @return the title.
\r
459 public String getTitle() {
\r
464 * Get a shorter title.
\r
466 * @return a shorter title.
\r
468 public String getShortTitle() {
\r
469 return _source.getName();
\r
475 * @return the source.
\r
478 public Source getSource() {
\r
483 public void actionPerformed(ActionEvent e) {
\r
484 EventDispatcher.dispatchEventAsync(this, "actionPerformedEff", new Object[] { e });
\r
492 public void actionPerformedEff(ActionEvent e) {
\r
493 if (_textField.getText().length() == 0)
\r
495 String prefix = "";
\r
496 prefix = _selector.getPrefix();
\r
498 if (!_textField.getText().startsWith("/")) {
\r
499 _source.sendUserString(prefix + _textField.getText());
\r
501 StringParser parser = new StringParser();
\r
502 String[] parts = parser.parseString(StringParser.trim(_textField.getText()));
\r
503 if (parts.length >= 2) {
\r
504 if (parts[0].toLowerCase(Locale.ENGLISH).equals("/join")) {
\r
505 _source.sendString("/focus Channel " + parts[1]);
\r
508 _source.sendUserString(_textField.getText());
\r
511 if (_textField != null)
\r
512 _textField.setText("");
\r
517 public void fontSelected(Font fnt) {
\r
518 _list.setFont(fnt);
\r
522 * Clear this awt source display.
\r
525 * source to be cleared.
\r
528 public void clear(Source source) {
\r
530 _scroll.setMaximum(_list.getLineCount() - 1);
\r
531 _scroll.setValue(_list.getLast());
\r
532 _listeners.sendEvent("eventOccured", this);
\r
536 * Test wether the specified line should be highlighted.
\r
540 * @return true if msg should be highlighted, false otherwise.
\r
542 protected boolean needHighLight(String msg) {
\r
543 msg = msg.toLowerCase(java.util.Locale.ENGLISH);
\r
544 if (_pixxConfiguration.highLightNick()) {
\r
545 String myNick = _source.getServer().getNick().toLowerCase(java.util.Locale.ENGLISH);
\r
546 if (msg.indexOf(myNick) != -1)
\r
550 Enumeration e = _pixxConfiguration.getHighLightWords();
\r
551 while (e.hasMoreElements()) {
\r
552 String word = ((String) (e.nextElement())).toLowerCase(java.util.Locale.ENGLISH);
\r
553 if (msg.indexOf(word) != -1)
\r
560 * Test wether the specified line should trigger "on word" sounds. Play the
\r
561 * sounds associated with the words.
\r
566 protected void checkSound(String msg) {
\r
567 msg = msg.toLowerCase(java.util.Locale.ENGLISH);
\r
568 AudioConfiguration ac = _pixxConfiguration.getIRCConfiguration().getAudioConfiguration();
\r
569 Enumeration e = ac.getSoundWords();
\r
570 while (e.hasMoreElements()) {
\r
571 String word = ((String) (e.nextElement())).toLowerCase(java.util.Locale.ENGLISH);
\r
572 if (msg.indexOf(word) != -1)
\r
578 * Print the given message on the awt source display.
\r
581 * message to print.
\r
585 * true if message should be in bold.
\r
587 * if message should be underlined.
\r
589 protected void print(String msg, int color, boolean bold, boolean underline) {
\r
591 msg = "\3" + color + msg;
\r
595 msg = ((char) 31) + msg;
\r
597 if (_pixxConfiguration.getB("timestamp")) {
\r
598 Calendar cal = Calendar.getInstance();
\r
599 String hour = "" + cal.get(Calendar.HOUR_OF_DAY);
\r
600 if (hour.length() == 1)
\r
602 String min = "" + cal.get(Calendar.MINUTE);
\r
603 if (min.length() == 1)
\r
605 msg = "[" + hour + ":" + min + "] " + msg;
\r
607 _list.addLine(msg);
\r
608 _scroll.setMaximum(_list.getLineCount() - 1);
\r
609 _scroll.setValue(_list.getLast());
\r
610 _listeners.sendEvent("eventOccured", this);
\r
614 * Print the given message on the awt source display.
\r
617 * message to print.
\r
621 protected void print(String msg, int color) {
\r
622 print(msg, color, false, false);
\r
626 * Print the given message on the awt source display.
\r
629 * message to print.
\r
631 protected void print(String msg) {
\r
632 print(msg, 1, false, false);
\r
635 private String formatNick(String nick) {
\r
636 return _nickPrefix + nick + _nickPostfix;
\r
640 public void messageReceived(String nick, String str, Source source) {
\r
642 if (needHighLight(str)) {
\r
643 print(formatNick(nick) + str, _pixxConfiguration.getI("highlightcolor"));
\r
645 print(formatNick(nick) + str);
\r
650 public void reportReceived(String msg, Source source) {
\r
655 public void noticeReceived(String from, String msg, Source source) {
\r
656 print("-" + from + "- " + msg, 5);
\r
660 public void action(String nick, String msg, Source source) {
\r
661 print("* " + nick + " " + msg, 6);
\r
665 * Leave this awt source.
\r
667 public void leave() {
\r
672 public void mouseWheelMoved(Integer amount) {
\r
673 int i = amount.intValue();
\r
674 _scroll.setValue(_scroll.getValue() + i);
\r
676 _list.setFirst(_scroll.getValue());
\r
678 _list.setLast(_scroll.getValue());
\r
682 public void valueChanged(PixxScrollBar pixScrollBar) {
\r
684 _list.setFirst(_scroll.getValue());
\r
686 _list.setLast(_scroll.getValue());
\r
690 public void focusGained(FocusEvent e) {
\r
691 if (e.getComponent() != _textField)
\r
692 _textField.requestFocus();
\r
696 public void focusLost(FocusEvent e) {
\r
700 public void channelEvent(StyledList lis, String chan, MouseEvent e) {
\r
701 if (_pixxConfiguration.matchMouseConfiguration("channeljoin", e)) {
\r
702 _source.sendString("/focus Channel " + chan);
\r
703 _source.sendString("/join " + chan);
\r
708 public void URLEvent(StyledList lis, String url, MouseEvent e) {
\r
709 if (_pixxConfiguration.matchMouseConfiguration("urlopen", e)) {
\r
710 _source.sendString("/url " + url);
\r
715 public void nickEvent(StyledList lis, String nick, MouseEvent e) {
\r
716 if (_pixxConfiguration.matchMouseConfiguration("nickquery", e)) {
\r
717 if (nick.equals(getSource().getServer().getNick()))
\r
719 if (_pixxConfiguration.getB("automaticqueries")) {
\r
720 _source.sendString("/focus Query " + nick);
\r
721 _source.sendString("/query " + nick);
\r
727 public String toString() {
\r
728 return "AWTSource : " + getStrippedTitle();
\r
732 public void setVisible(boolean b) {
\r
733 super.setVisible(b);
\r
739 public void copyEvent(StyledList lis, String txt, MouseEvent e) {
\r
740 Frame f = new Frame();
\r
741 f.setTitle(getText(IRCTextProvider.GUI_COPY_WINDOW));
\r
742 f.addWindowListener(this);
\r
743 f.setLayout(new GridLayout(1, 1));
\r
744 Panel p = new Panel();
\r
745 p.setLayout(new GridLayout(1, 1));
\r
747 TextArea c = new TextArea();
\r
748 c.setFont(new Font("", Font.PLAIN, 12));
\r
752 f.setSize(400, 300);
\r
757 public void virtualSizeChanged(StyledList lis) {
\r
761 public void windowActivated(WindowEvent e) {
\r
765 public void windowClosed(WindowEvent e) {
\r
769 public void windowClosing(WindowEvent e) {
\r
770 e.getWindow().hide();
\r
771 e.getWindow().dispose();
\r
775 public void windowDeactivated(WindowEvent e) {
\r
779 public void windowDeiconified(WindowEvent e) {
\r
783 public void windowIconified(WindowEvent e) {
\r
787 public void windowOpened(WindowEvent e) {
\r