[3102] | 1 | /* |
---|
| 2 | * Jeti, a Java Jabber client, Copyright (C) 2001 E.S. de Boer |
---|
| 3 | * |
---|
| 4 | * This program is free software; you can redistribute it and/or modify |
---|
| 5 | * it under the terms of the GNU General Public License as published by |
---|
| 6 | * the Free Software Foundation; either version 2 of the License, or |
---|
| 7 | * (at your option) any later version. |
---|
| 8 | * |
---|
| 9 | * This program is distributed in the hope that it will be useful, |
---|
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 12 | * GNU General Public License for more details. |
---|
| 13 | * |
---|
| 14 | * You should have received a copy of the GNU General Public License |
---|
| 15 | * along with this program; if not, write to the Free Software |
---|
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
| 17 | * |
---|
| 18 | * For questions, comments etc, |
---|
| 19 | * use the website at http://jeti.jabberstudio.org |
---|
| 20 | * or mail/IM me at jeti@jabber.org |
---|
| 21 | * |
---|
| 22 | * Created on 8-jan-2005 |
---|
| 23 | */ |
---|
| 24 | |
---|
| 25 | package nu.fw.jeti.ui; |
---|
| 26 | |
---|
| 27 | import java.awt.*; |
---|
| 28 | import java.awt.event.*; |
---|
| 29 | import java.text.MessageFormat; |
---|
| 30 | import java.util.ArrayList; |
---|
| 31 | import java.util.Iterator; |
---|
| 32 | import java.util.List; |
---|
| 33 | |
---|
| 34 | import javax.swing.*; |
---|
| 35 | import javax.swing.event.ChangeEvent; |
---|
| 36 | import javax.swing.event.ChangeListener; |
---|
| 37 | |
---|
| 38 | import nu.fw.jeti.events.MessageEventListener; |
---|
| 39 | import nu.fw.jeti.events.MessageListener; |
---|
| 40 | import nu.fw.jeti.events.PresenceListener; |
---|
| 41 | import nu.fw.jeti.images.StatusIcons; |
---|
| 42 | import nu.fw.jeti.jabber.Backend; |
---|
| 43 | import nu.fw.jeti.jabber.JID; |
---|
| 44 | import nu.fw.jeti.jabber.JIDStatus; |
---|
| 45 | import nu.fw.jeti.jabber.UnknownJIDStatus; |
---|
| 46 | import nu.fw.jeti.jabber.elements.Message; |
---|
| 47 | import nu.fw.jeti.jabber.elements.Presence; |
---|
| 48 | import nu.fw.jeti.jabber.elements.XMessageEvent; |
---|
| 49 | import nu.fw.jeti.util.I18N; |
---|
| 50 | import nu.fw.jeti.util.Preferences; |
---|
| 51 | |
---|
| 52 | /** |
---|
| 53 | * @author E.S. de Boer |
---|
| 54 | * |
---|
| 55 | */ |
---|
| 56 | public class ChatWindows implements MessageListener, MessageEventListener,PresenceListener |
---|
| 57 | { |
---|
| 58 | private static final int MAX_TABNAME_LENGTH = 100; |
---|
| 59 | private List chatWindows = new ArrayList(); |
---|
| 60 | private Backend backend; |
---|
| 61 | private JTabbedPane tabs; |
---|
| 62 | private JFrame window; |
---|
| 63 | private int dividerLocation; |
---|
| 64 | private ComponentListener dividerListener; |
---|
| 65 | |
---|
| 66 | public ChatWindows(Backend backend) |
---|
| 67 | { |
---|
| 68 | this.backend = backend; |
---|
| 69 | backend.addListener(MessageListener.class, this); |
---|
| 70 | backend.addListener(MessageEventListener.class, this); |
---|
| 71 | backend.addListener(PresenceListener.class, this); |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | public synchronized void exit() |
---|
| 75 | { |
---|
| 76 | for(Iterator i = chatWindows.iterator();i.hasNext();) |
---|
| 77 | { |
---|
| 78 | ((ChatWindow)i.next()).exit(); |
---|
| 79 | } |
---|
| 80 | if(window!=null)window.dispose(); |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | /** |
---|
| 84 | * Open a new chat window, or add to a existing one. |
---|
| 85 | * A chat exists when a chatwindow matching the jid |
---|
| 86 | * including the resource exists |
---|
| 87 | * @param jidStatus the jid to chat with |
---|
| 88 | */ |
---|
| 89 | public synchronized void chatResource(JIDStatus jidStatus) |
---|
| 90 | { |
---|
| 91 | ChatWindow w = getChatwindow(jidStatus.getJID(),true); |
---|
| 92 | if(w==null) |
---|
| 93 | { |
---|
| 94 | w = startChat(jidStatus, backend.createThread()); |
---|
| 95 | } |
---|
| 96 | chat(w); |
---|
| 97 | } |
---|
| 98 | |
---|
| 99 | /** |
---|
| 100 | * Open a new chat window, or add to a existing one. |
---|
| 101 | * A chat exists when a chatwindow matching the jid |
---|
| 102 | * exists (resources are not considered) |
---|
| 103 | * @param jidStatus the jid to chat with |
---|
| 104 | */ |
---|
| 105 | public synchronized void chat(JIDStatus jidStatus) |
---|
| 106 | { |
---|
| 107 | ChatWindow w = getChatwindow(jidStatus.getJID(),Preferences.getBoolean("jeti","chatwindowPerResource",false)); |
---|
| 108 | if(w==null) w = startChat(jidStatus, backend.createThread()); |
---|
| 109 | else { |
---|
| 110 | //unminimize chatwindow if it exist |
---|
| 111 | if(w.getTopLevelAncestor() instanceof JFrame) |
---|
| 112 | { |
---|
| 113 | JFrame frame = (JFrame)w.getTopLevelAncestor(); |
---|
| 114 | if(frame.getExtendedState()==Frame.ICONIFIED) |
---|
| 115 | { |
---|
| 116 | frame.setState(Frame.NORMAL); |
---|
| 117 | } |
---|
| 118 | frame.toFront(); |
---|
| 119 | } |
---|
| 120 | } |
---|
| 121 | chat(w); |
---|
| 122 | } |
---|
| 123 | |
---|
| 124 | /** |
---|
| 125 | * Gets a new chat panel |
---|
| 126 | * @param jidStatus the jid to chat with |
---|
| 127 | */ |
---|
| 128 | public synchronized JPanel createChatPanel(JIDStatus jidStatus) |
---|
| 129 | { |
---|
| 130 | JFrame frame = new JFrame(); |
---|
| 131 | ChatWindow chatWindow = new ChatWindow(backend,this,frame, jidStatus,backend.createThread()); |
---|
| 132 | chatWindows.add(chatWindow); |
---|
| 133 | return chatWindow; |
---|
| 134 | } |
---|
| 135 | |
---|
| 136 | private void chat(ChatWindow w) |
---|
| 137 | { |
---|
| 138 | |
---|
| 139 | if(tabs!=null) |
---|
| 140 | { |
---|
| 141 | if(tabs.indexOfComponent(w)!=-1) |
---|
| 142 | { |
---|
| 143 | w.requestFocusInWindow(); |
---|
| 144 | tabs.setSelectedComponent(w); |
---|
| 145 | } |
---|
| 146 | } |
---|
| 147 | ((Window)w.getTopLevelAncestor()).toFront(); |
---|
| 148 | } |
---|
| 149 | |
---|
| 150 | private ChatWindow startChat(JIDStatus jidStatus, String thread) |
---|
| 151 | { |
---|
| 152 | ChatWindow chatWindow; |
---|
| 153 | if(Preferences.getBoolean("jeti", "tabs", false)) |
---|
| 154 | { |
---|
| 155 | if(window==null) makeNewTabWindow(); |
---|
| 156 | chatWindow = new ChatWindow(backend,this,window,jidStatus,thread ); |
---|
| 157 | if(!window.isDisplayable()) addMenu(chatWindow); |
---|
| 158 | addTab(jidStatus, chatWindow); |
---|
| 159 | chatWindow.setDividerLocation(dividerLocation); |
---|
| 160 | chatWindow.addSplitBarListener(dividerListener); |
---|
| 161 | tabs.setBackgroundAt(tabs.getTabCount()-1,Color.BLUE); |
---|
| 162 | tabs.setForegroundAt(tabs.getTabCount()-1,Color.RED); |
---|
| 163 | window.setVisible(true); |
---|
| 164 | } |
---|
| 165 | else |
---|
| 166 | { |
---|
| 167 | chatWindow = new ChatWindow(backend,this,null, jidStatus,thread ); |
---|
| 168 | setChatWindowPosition(chatWindow); |
---|
| 169 | } |
---|
| 170 | chatWindows.add(chatWindow); |
---|
| 171 | return chatWindow; |
---|
| 172 | } |
---|
| 173 | |
---|
| 174 | private void addTab(JIDStatus jidStatus, ChatWindow chatWindow) |
---|
| 175 | { |
---|
| 176 | String name = jidStatus.getNick(); |
---|
| 177 | // = new FontMetrics((Font)UIManager.get(name)); |
---|
| 178 | FontMetrics fontMetrics = tabs.getFontMetrics(tabs.getFont()); |
---|
| 179 | name+=" "; |
---|
| 180 | int fontLenght=0; |
---|
| 181 | for(int i=0;i<name.length();i++) |
---|
| 182 | { |
---|
| 183 | fontLenght+=fontMetrics.charWidth(name.charAt(i)); |
---|
| 184 | if(fontLenght>=MAX_TABNAME_LENGTH) |
---|
| 185 | { |
---|
| 186 | name = name.substring(0,i); |
---|
| 187 | break; |
---|
| 188 | } |
---|
| 189 | } |
---|
| 190 | tabs.addTab(name,StatusIcons.getStatusIcon(jidStatus),chatWindow); |
---|
| 191 | } |
---|
| 192 | |
---|
| 193 | private void removeTab(ChatWindow chatWindow) |
---|
| 194 | { |
---|
| 195 | if(tabs.getTabCount()==1) |
---|
| 196 | { |
---|
| 197 | window.dispose(); |
---|
| 198 | window=null; |
---|
| 199 | } |
---|
| 200 | tabs.remove(chatWindow); |
---|
| 201 | } |
---|
| 202 | |
---|
| 203 | private void makeNewTabWindow() |
---|
| 204 | { |
---|
| 205 | window = new JFrame(); |
---|
| 206 | //window.setIconImage(nu.fw.jeti.images.StatusIcons.getImageIcon("jeti").getImage()); |
---|
| 207 | JMenuBar bar = new JMenuBar(); |
---|
| 208 | tabs = new JTabbedPane(SwingConstants.LEFT) |
---|
| 209 | {//fix problem that change event is not called if there are tabs to the right |
---|
| 210 | public void remove(Component component) |
---|
| 211 | { |
---|
| 212 | super.remove( component ); |
---|
| 213 | fireStateChanged(); |
---|
| 214 | } |
---|
| 215 | }; |
---|
| 216 | |
---|
| 217 | tabs.addChangeListener(new ChangeListener() |
---|
| 218 | { |
---|
| 219 | public void stateChanged(ChangeEvent e) |
---|
| 220 | { |
---|
| 221 | Runnable updateAComponent = new Runnable() |
---|
| 222 | { |
---|
| 223 | public void run() |
---|
| 224 | { |
---|
| 225 | ChatWindow w = (ChatWindow) tabs.getSelectedComponent(); |
---|
| 226 | if(w!=null) |
---|
| 227 | { |
---|
| 228 | JIDStatus j = w.getJIDStatus(); |
---|
| 229 | window.setTitle(j.getNick()); |
---|
| 230 | window.setIconImage(StatusIcons.getStatusIcon(j).getImage()); |
---|
| 231 | tabs.setBackgroundAt(tabs.getSelectedIndex() |
---|
| 232 | ,UIManager.getColor("TabbedPane.background")); |
---|
| 233 | tabs.setForegroundAt(tabs.getSelectedIndex() |
---|
| 234 | ,UIManager.getColor("TabbedPane.foreground")); |
---|
| 235 | window.getJMenuBar().removeAll(); |
---|
| 236 | addMenu(w); |
---|
| 237 | w.setDividerLocation(dividerLocation); |
---|
| 238 | } |
---|
| 239 | } |
---|
| 240 | }; |
---|
| 241 | SwingUtilities.invokeLater(updateAComponent); |
---|
| 242 | } |
---|
| 243 | }); |
---|
| 244 | |
---|
| 245 | tabs.addMouseListener(new MouseAdapter() |
---|
| 246 | { |
---|
| 247 | public void mousePressed(MouseEvent e) |
---|
| 248 | { |
---|
| 249 | if(e.getButton() == MouseEvent.BUTTON3) |
---|
| 250 | { |
---|
| 251 | ChatWindow w =(ChatWindow)((JTabbedPane) |
---|
| 252 | e.getSource()).getSelectedComponent(); |
---|
| 253 | if(w!=null) |
---|
| 254 | { |
---|
| 255 | JPopupMenu menu = tabMenu(w); |
---|
| 256 | menu.show(tabs, e.getX(),e.getY()); |
---|
| 257 | } |
---|
| 258 | } |
---|
| 259 | } |
---|
| 260 | }); |
---|
| 261 | addCtrlTabFocus(); |
---|
| 262 | window.setJMenuBar(bar); |
---|
| 263 | window.setSize(Preferences.getInteger("jeti","chatTabWidth",500),Preferences.getInteger("jeti","chatTabHeight",400)); |
---|
| 264 | int posX = Preferences.getInteger("jeti","chatTabPosX",100); |
---|
| 265 | int posY = Preferences.getInteger("jeti","chatTabPosY",100); |
---|
| 266 | int screenX = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(); |
---|
| 267 | int screenY = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight(); |
---|
| 268 | if(posX>screenX) posX=100; |
---|
| 269 | if(posY>screenY) posY=100; |
---|
| 270 | window.setLocation(posX,posY); |
---|
| 271 | window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); |
---|
| 272 | window.addWindowListener(new WindowAdapter() |
---|
| 273 | { |
---|
| 274 | public void windowClosing(WindowEvent e) |
---|
| 275 | { |
---|
| 276 | Preferences.putInteger("jeti","chatTabPosX",window.getX()); |
---|
| 277 | Preferences.putInteger("jeti","chatTabPosY",window.getY()); |
---|
| 278 | Preferences.putInteger("jeti","chatTabHeight",window.getHeight()); |
---|
| 279 | Preferences.putInteger("jeti","chatTabWidth",window.getWidth()); |
---|
| 280 | Preferences.putInteger("jeti","chatTabDivider",dividerLocation); |
---|
| 281 | if(!askIfClose())return; |
---|
| 282 | int tabCount = tabs.getTabCount(); |
---|
| 283 | for(int i =0;i<tabCount;i++) |
---|
| 284 | { |
---|
| 285 | ChatWindow c = (ChatWindow)tabs.getComponent(i); |
---|
| 286 | c.exit(); |
---|
| 287 | removeChatWindow(c); |
---|
| 288 | } |
---|
| 289 | tabs.removeAll(); |
---|
| 290 | window.dispose(); |
---|
| 291 | window=null; |
---|
| 292 | } |
---|
| 293 | }); |
---|
| 294 | window.addWindowFocusListener(new WindowAdapter() |
---|
| 295 | { |
---|
| 296 | public void windowGainedFocus(WindowEvent e) |
---|
| 297 | { |
---|
| 298 | ChatWindow c= (ChatWindow)tabs.getSelectedComponent(); |
---|
| 299 | if(c!=null)c.requestFocusInWindow(); |
---|
| 300 | } |
---|
| 301 | }); |
---|
| 302 | window.getContentPane().add(tabs); |
---|
| 303 | dividerLocation = Preferences.getInteger("jeti","chatTabDivider",200); |
---|
| 304 | dividerListener = new ComponentAdapter(){ |
---|
| 305 | public void componentMoved(ComponentEvent e){ |
---|
| 306 | dividerLocation = ((JSplitPane)e.getComponent().getParent()).getDividerLocation(); |
---|
| 307 | } |
---|
| 308 | }; |
---|
| 309 | } |
---|
| 310 | |
---|
| 311 | private void addCtrlTabFocus() |
---|
| 312 | { |
---|
| 313 | InputMap im = tabs.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); |
---|
| 314 | ActionMap am = tabs.getActionMap(); |
---|
| 315 | Action forwardAction = new AbstractAction() |
---|
| 316 | { |
---|
| 317 | public void actionPerformed(ActionEvent e) |
---|
| 318 | { |
---|
| 319 | int idx = tabs.getSelectedIndex(); |
---|
| 320 | if (idx != -1) { |
---|
| 321 | idx = (idx + 1) % tabs.getTabCount(); |
---|
| 322 | //tabs.requestFocusInWindow(); |
---|
| 323 | tabs.setSelectedIndex(idx); |
---|
| 324 | focusTab(); |
---|
| 325 | } |
---|
| 326 | } |
---|
| 327 | }; |
---|
| 328 | KeyStroke forwardStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK); |
---|
| 329 | im.put(forwardStroke, "myForwardAction"); |
---|
| 330 | am.put("myForwardAction", forwardAction); |
---|
| 331 | |
---|
| 332 | Action backwardAction = new AbstractAction() |
---|
| 333 | { |
---|
| 334 | public void actionPerformed(ActionEvent e) |
---|
| 335 | { |
---|
| 336 | int idx = tabs.getSelectedIndex(); |
---|
| 337 | idx = (idx - 1); |
---|
| 338 | if (idx < 0) idx = tabs.getTabCount()-1; |
---|
| 339 | tabs.setSelectedIndex(idx); |
---|
| 340 | focusTab(); |
---|
| 341 | } |
---|
| 342 | }; |
---|
| 343 | KeyStroke backwardStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_DOWN_MASK + InputEvent.CTRL_DOWN_MASK); |
---|
| 344 | im.put(backwardStroke, "myBackwardAction"); |
---|
| 345 | am.put("myBackwardAction", backwardAction); |
---|
| 346 | |
---|
| 347 | } |
---|
| 348 | |
---|
| 349 | private void focusTab() |
---|
| 350 | { |
---|
| 351 | SwingUtilities.invokeLater(new Runnable() { |
---|
| 352 | public void run() { |
---|
| 353 | tabs.getSelectedComponent().requestFocusInWindow(); |
---|
| 354 | } |
---|
| 355 | }); |
---|
| 356 | } |
---|
| 357 | |
---|
| 358 | public boolean askIfClose() |
---|
| 359 | { |
---|
| 360 | if(tabs==null)return true; |
---|
| 361 | int tabCount = tabs.getTabCount(); |
---|
| 362 | if(tabCount>1) |
---|
| 363 | { |
---|
| 364 | int answer = JOptionPane.showConfirmDialog(window,MessageFormat.format(I18N.gettext("main.chat.You_are_about_to_close_{0}_tabs_Are_you_sure_you_want_to_close_them?") |
---|
| 365 | ,new Object[]{new Integer(tabCount)}),"" |
---|
| 366 | ,JOptionPane.YES_NO_OPTION); |
---|
| 367 | if(answer==JOptionPane.NO_OPTION)return false; |
---|
| 368 | } |
---|
| 369 | return true; |
---|
| 370 | } |
---|
| 371 | |
---|
| 372 | private void addMenu(final ChatWindow chatWindow) |
---|
| 373 | { |
---|
| 374 | final JMenu menu = chatWindow.getMenu(); |
---|
| 375 | if(menu.getItem(menu.getItemCount()-1).getName()==null) |
---|
| 376 | { |
---|
| 377 | final JMenuItem menuMoveToWindow = new JMenuItem(); |
---|
| 378 | final JMenuItem menuClose = new JMenuItem(); |
---|
| 379 | I18N.setTextAndMnemonic("main.chat.menu.Move_to_Window",menuMoveToWindow,true); |
---|
| 380 | menuMoveToWindow.addActionListener(new java.awt.event.ActionListener() |
---|
| 381 | { |
---|
| 382 | public void actionPerformed(ActionEvent e) |
---|
| 383 | { |
---|
| 384 | menu.remove(menuMoveToWindow); |
---|
| 385 | menu.remove(menuClose); |
---|
| 386 | removeTab(chatWindow); |
---|
| 387 | chatWindow.removeSplitBarListener(dividerListener); |
---|
| 388 | chatWindow.changeToWindow(); |
---|
| 389 | setChatWindowPosition(chatWindow); |
---|
| 390 | } |
---|
| 391 | }); |
---|
| 392 | menu.add(menuMoveToWindow); |
---|
| 393 | I18N.setTextAndMnemonic("main.chat.menu.Close",menuClose,true); |
---|
| 394 | menuClose.addActionListener(new ActionListener() |
---|
| 395 | { |
---|
| 396 | public void actionPerformed(ActionEvent e) |
---|
| 397 | { |
---|
| 398 | chatWindow.removeSplitBarListener(dividerListener); |
---|
| 399 | chatWindow.exit(); |
---|
| 400 | chatWindows.remove(chatWindow); |
---|
| 401 | removeTab(chatWindow); |
---|
| 402 | } |
---|
| 403 | }); |
---|
| 404 | menuClose.setName("close"); |
---|
| 405 | menu.add(menuClose); |
---|
| 406 | } |
---|
| 407 | window.getJMenuBar().add(menu); |
---|
| 408 | } |
---|
| 409 | |
---|
| 410 | private JPopupMenu tabMenu(final ChatWindow chatWindow) |
---|
| 411 | { |
---|
| 412 | JPopupMenu groupPopupMenu = new JPopupMenu(); |
---|
| 413 | JMenuItem menuItem = null; |
---|
| 414 | |
---|
| 415 | menuItem = new JMenuItem(); |
---|
| 416 | I18N.setTextAndMnemonic("main.chat.menu.Close",menuItem,true); |
---|
| 417 | menuItem.addActionListener(new ActionListener() |
---|
| 418 | { |
---|
| 419 | public void actionPerformed(ActionEvent e) |
---|
| 420 | { |
---|
| 421 | chatWindow.removeSplitBarListener(dividerListener); |
---|
| 422 | chatWindow.exit(); |
---|
| 423 | chatWindows.remove(chatWindow); |
---|
| 424 | removeTab(chatWindow); |
---|
| 425 | } |
---|
| 426 | }); |
---|
| 427 | groupPopupMenu.add(menuItem); |
---|
| 428 | return groupPopupMenu; |
---|
| 429 | } |
---|
| 430 | |
---|
| 431 | public void convertToTab(ChatWindow cw,JIDStatus jidStatus) |
---|
| 432 | { |
---|
| 433 | if(window==null)makeNewTabWindow(); |
---|
| 434 | if(!window.isDisplayable()) addMenu(cw); |
---|
| 435 | addTab(jidStatus,cw); |
---|
| 436 | cw.setDividerLocation(dividerLocation); |
---|
| 437 | cw.addSplitBarListener(dividerListener); |
---|
| 438 | cw.setParentFrame(window); |
---|
| 439 | window.setVisible(true); |
---|
| 440 | } |
---|
| 441 | |
---|
| 442 | public synchronized void presenceChanged(Presence presence) |
---|
| 443 | { |
---|
| 444 | ChatWindow cw = getChatwindow(presence.getFrom() |
---|
| 445 | ,Preferences.getBoolean("jeti","chatwindowPerResource",false)); |
---|
| 446 | if(cw!=null) cw.appendPresenceChange(presence); |
---|
| 447 | } |
---|
| 448 | |
---|
| 449 | private void beep() |
---|
| 450 | { |
---|
| 451 | if (Preferences.getBoolean("jeti","beep",true)) |
---|
| 452 | java.awt.Toolkit.getDefaultToolkit().beep(); |
---|
| 453 | } |
---|
| 454 | |
---|
| 455 | public void setTitleAt(ChatWindow cw, String title) |
---|
| 456 | { |
---|
| 457 | int index = tabs.indexOfComponent(cw); |
---|
| 458 | tabs.setTitleAt(index, title); |
---|
| 459 | if(tabs.getSelectedIndex()==index) |
---|
| 460 | { |
---|
| 461 | window.setTitle(title); |
---|
| 462 | } |
---|
| 463 | } |
---|
| 464 | |
---|
| 465 | public void setIconAt(ChatWindow cw, ImageIcon icon) |
---|
| 466 | { |
---|
| 467 | int index = tabs.indexOfComponent(cw); |
---|
| 468 | tabs.setIconAt(index, icon); |
---|
| 469 | if(tabs.getSelectedIndex()==index) |
---|
| 470 | { |
---|
| 471 | window.setIconImage(icon.getImage()); |
---|
| 472 | } |
---|
| 473 | } |
---|
| 474 | |
---|
| 475 | // ---------------------message event--------------------------- |
---|
| 476 | public synchronized void message(Message message) |
---|
| 477 | { |
---|
| 478 | JID from = message.getFrom(); |
---|
| 479 | if (message.getType().equals("chat") || (message.getType().equals("error") && message.getThread() != null)) |
---|
| 480 | { |
---|
| 481 | beep(); |
---|
| 482 | ChatWindow chatWindow; |
---|
| 483 | JIDStatus jidStatus = backend.getJIDStatus(message.getFrom()); |
---|
| 484 | String server = from.getDomain(); |
---|
| 485 | if(server.indexOf("conference")>-1 || |
---|
| 486 | server.indexOf("private")>-1 || |
---|
| 487 | server.indexOf("groupchat")>-1) |
---|
| 488 | {//private messages from groupchat should have a window per resource |
---|
| 489 | chatWindow = getChatwindow(from,true); |
---|
| 490 | jidStatus = new UnknownJIDStatus(from,from.getResource()); |
---|
| 491 | } |
---|
| 492 | else chatWindow = getChatwindow(from,Preferences.getBoolean("jeti","chatwindowPerResource",false)); |
---|
| 493 | if(tabs!=null) |
---|
| 494 | { |
---|
| 495 | int index = tabs.indexOfComponent(chatWindow); |
---|
| 496 | if(index!=-1) |
---|
| 497 | { |
---|
| 498 | if(tabs.getSelectedIndex()!=index) |
---|
| 499 | { |
---|
| 500 | tabs.setBackgroundAt(index,Color.BLUE); |
---|
| 501 | tabs.setForegroundAt(index,Color.RED); |
---|
| 502 | } |
---|
| 503 | tabs.setToolTipTextAt(index,message.getBody()); |
---|
| 504 | } |
---|
| 505 | } |
---|
| 506 | if (chatWindow == null) |
---|
| 507 | { |
---|
| 508 | if (jidStatus == null) chatWindow = startChat(new UnknownJIDStatus(from),message.getThread()); // ,"images",true,"unknown",e.getThread()); |
---|
| 509 | else chatWindow = startChat(jidStatus, message.getThread()); |
---|
| 510 | } |
---|
| 511 | chatWindow.appendMessage(message); |
---|
| 512 | } |
---|
| 513 | else if(message.getType().equals("groupchat")) |
---|
| 514 | { |
---|
| 515 | if(from.getResource()!=null) beep(); |
---|
| 516 | } |
---|
| 517 | else |
---|
| 518 | { |
---|
| 519 | beep(); |
---|
| 520 | new SendMessage(backend, message); |
---|
| 521 | } |
---|
| 522 | } |
---|
| 523 | |
---|
| 524 | private ChatWindow getChatwindow(JID jid,boolean matchResources) |
---|
| 525 | { |
---|
| 526 | String resource =jid.getResource(); |
---|
| 527 | ChatWindow cw=null; |
---|
| 528 | for (int tel = 0; tel < chatWindows.size(); tel++) |
---|
| 529 | { |
---|
| 530 | JID cwJID = ((ChatWindow)chatWindows.get(tel)).getJIDStatus().getCompleteJID(); |
---|
| 531 | if (cwJID.equals(jid)) |
---|
| 532 | { |
---|
| 533 | if(resource!=null && resource.equals(cwJID.getResource())) |
---|
| 534 | { |
---|
| 535 | return (ChatWindow) chatWindows.get(tel); |
---|
| 536 | } |
---|
| 537 | else if(!matchResources) cw = (ChatWindow) chatWindows.get(tel); |
---|
| 538 | } |
---|
| 539 | } |
---|
| 540 | return cw; |
---|
| 541 | } |
---|
| 542 | |
---|
| 543 | private void setChatWindowPosition(ChatWindow chatWindow) |
---|
| 544 | { |
---|
| 545 | if(chatWindows.isEmpty()) |
---|
| 546 | { |
---|
| 547 | int posX = Preferences.getInteger("jeti","chatPosX",100); |
---|
| 548 | int posY = Preferences.getInteger("jeti","chatPosY",100); |
---|
| 549 | int screenX = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(); |
---|
| 550 | int screenY = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight(); |
---|
| 551 | if(posX>screenX) posX=100; |
---|
| 552 | if(posY>screenY) posY=100; |
---|
| 553 | chatWindow.setLocationOnScreen(posX,posY); |
---|
| 554 | } |
---|
| 555 | else |
---|
| 556 | { |
---|
| 557 | ChatWindow oldWindow = (ChatWindow)chatWindows.get(chatWindows.size()-1); |
---|
| 558 | chatWindow.setLocationOnScreen(oldWindow); |
---|
| 559 | } |
---|
| 560 | } |
---|
| 561 | |
---|
| 562 | public synchronized void removeChatWindow(ChatWindow chatWindow) |
---|
| 563 | { |
---|
| 564 | chatWindows.remove(chatWindow); |
---|
| 565 | } |
---|
| 566 | |
---|
| 567 | public synchronized void onComposing(JID from, String thread, XMessageEvent messageEvent) |
---|
| 568 | { |
---|
| 569 | ChatWindow chatWindow = null; |
---|
| 570 | { |
---|
| 571 | chatWindow = getChatwindow(from,Preferences.getBoolean("jeti","chatwindowPerResource",false)); |
---|
| 572 | if(chatWindow!=null)chatWindow.composing(messageEvent.getType()); |
---|
| 573 | } |
---|
| 574 | } |
---|
| 575 | |
---|
| 576 | public synchronized void requestComposing(JID from, String id, String thread) |
---|
| 577 | { |
---|
| 578 | ChatWindow chatWindow = null; |
---|
| 579 | { |
---|
| 580 | chatWindow = getChatwindow(from,Preferences.getBoolean("jeti","chatwindowPerResource",false)); |
---|
| 581 | if(chatWindow!=null)chatWindow.composingID(id); |
---|
| 582 | } |
---|
| 583 | } |
---|
| 584 | } |
---|