[1014] | 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 me at jeti@jabberstudio.org |
---|
| 21 | * created 2001 |
---|
| 22 | */ |
---|
| 23 | |
---|
| 24 | package nu.fw.jeti.ui; |
---|
| 25 | |
---|
| 26 | import java.awt.Color; |
---|
| 27 | import java.awt.Component; |
---|
| 28 | import java.awt.Dimension; |
---|
| 29 | import java.awt.event.*; |
---|
| 30 | import java.text.MessageFormat; |
---|
| 31 | import java.util.*; |
---|
| 32 | |
---|
| 33 | import javax.swing.*; |
---|
| 34 | import javax.swing.Timer; |
---|
| 35 | import javax.swing.tree.DefaultTreeCellRenderer; |
---|
| 36 | import javax.swing.tree.TreeCellRenderer; |
---|
| 37 | import javax.swing.tree.TreeModel; |
---|
| 38 | import javax.swing.tree.TreePath; |
---|
| 39 | |
---|
| 40 | import nu.fw.jeti.backend.roster.JIDStatusGroup; |
---|
| 41 | import nu.fw.jeti.backend.roster.JIDStatusTree; |
---|
| 42 | import nu.fw.jeti.backend.roster.PrimaryJIDStatus; |
---|
| 43 | import nu.fw.jeti.images.StatusIcons; |
---|
| 44 | import nu.fw.jeti.jabber.Backend; |
---|
| 45 | import nu.fw.jeti.jabber.JID; |
---|
| 46 | import nu.fw.jeti.jabber.JIDStatus; |
---|
| 47 | import nu.fw.jeti.jabber.elements.*; |
---|
| 48 | import nu.fw.jeti.plugins.PluginsInfo; |
---|
| 49 | import nu.fw.jeti.plugins.RosterMenuListener; |
---|
| 50 | import nu.fw.jeti.util.I18N; |
---|
| 51 | import nu.fw.jeti.util.Preferences; |
---|
| 52 | import nu.fw.jeti.util.TreeExpander; |
---|
| 53 | |
---|
| 54 | /** |
---|
| 55 | * @author E.S. de Boer |
---|
| 56 | */ |
---|
| 57 | |
---|
| 58 | public class RosterTree extends JTree |
---|
| 59 | { |
---|
| 60 | private Backend backend; |
---|
| 61 | private JPopupMenu popupMenu; |
---|
| 62 | private JPopupMenu groupPopupMenu; |
---|
| 63 | private JIDStatus currentJIDStatus; |
---|
| 64 | private JIDStatusGroup currentJIDStatusGroup2; |
---|
| 65 | private JIDStatusGroup currentJIDStatusGroup; |
---|
| 66 | private boolean onlineTree; |
---|
| 67 | private Jeti main; |
---|
| 68 | private String currentGroup; |
---|
| 69 | private Map menuItems; //added menus |
---|
| 70 | private TreeExpander treeExpander; |
---|
| 71 | |
---|
| 72 | /** |
---|
| 73 | * @param type True for an online tree |
---|
| 74 | */ |
---|
| 75 | public RosterTree( Backend backend, Jeti main, boolean onlineTree, TreeModel model ) |
---|
| 76 | { |
---|
| 77 | super(model); |
---|
| 78 | this.onlineTree = onlineTree; |
---|
| 79 | this.backend = backend; |
---|
| 80 | this.main = main; |
---|
| 81 | |
---|
| 82 | ToolTipManager.sharedInstance().registerComponent(this); |
---|
| 83 | |
---|
| 84 | setRootVisible(false); |
---|
| 85 | setToggleClickCount(0);//set expanding on mouseclicks of because |
---|
| 86 | // detection needed for single or double click |
---|
| 87 | |
---|
| 88 | javax.swing.plaf.basic.BasicTreeUI basicTreeUI = (javax.swing.plaf.basic.BasicTreeUI) getUI(); |
---|
| 89 | basicTreeUI.setRightChildIndent(1); |
---|
| 90 | basicTreeUI.setLeftChildIndent(1); |
---|
| 91 | basicTreeUI.setExpandedIcon(null); |
---|
| 92 | basicTreeUI.setCollapsedIcon(null); |
---|
| 93 | putClientProperty("JTree.lineStyle", "None"); |
---|
| 94 | |
---|
| 95 | createPopupMenu(); |
---|
| 96 | createGroupPopupMenu(); |
---|
| 97 | if (UIManager.getLookAndFeel().isNativeLookAndFeel()) |
---|
| 98 | { |
---|
| 99 | setCellRenderer(new MacRenderer()); |
---|
| 100 | if (onlineTree) |
---|
| 101 | { |
---|
| 102 | treeExpander = new TreeExpander(this, model); |
---|
| 103 | } |
---|
| 104 | } |
---|
| 105 | else setCellRenderer(new MyRenderer()); |
---|
| 106 | |
---|
| 107 | addMouseListener(new MouseAdapter() |
---|
| 108 | { |
---|
| 109 | //save tree path for single click event |
---|
| 110 | TreePath lastTreePath; |
---|
| 111 | |
---|
| 112 | //timer needed to check if double or single mouseclick |
---|
| 113 | Timer timer = new Timer(300, new ActionListener() |
---|
| 114 | { |
---|
| 115 | public void actionPerformed(ActionEvent e) |
---|
| 116 | { |
---|
| 117 | if (isExpanded(lastTreePath)) collapsePath(lastTreePath); |
---|
| 118 | else expandPath(lastTreePath); |
---|
| 119 | timer.stop(); |
---|
| 120 | } |
---|
| 121 | }); |
---|
| 122 | |
---|
| 123 | public void mousePressed(MouseEvent e) |
---|
| 124 | { |
---|
| 125 | TreePath selPath = getPathForLocation(e.getX(), e.getY()); |
---|
| 126 | if (selPath != null) |
---|
| 127 | { |
---|
| 128 | setSelectionPath(selPath); |
---|
| 129 | Object o = selPath.getLastPathComponent(); |
---|
| 130 | if (o instanceof JIDStatusGroup) |
---|
| 131 | {//group |
---|
| 132 | maybeShowGroupPopup(e, (JIDStatusGroup) o); |
---|
| 133 | if (SwingUtilities.isLeftMouseButton(e)) |
---|
| 134 | { |
---|
| 135 | if (isExpanded(selPath)) collapsePath(selPath); |
---|
| 136 | else expandPath(selPath); |
---|
| 137 | } |
---|
| 138 | } |
---|
| 139 | else |
---|
| 140 | { |
---|
| 141 | JIDStatusGroup group = null; |
---|
| 142 | JIDStatus jidStatus = null; |
---|
| 143 | if (o instanceof PrimaryJIDStatus) |
---|
| 144 | { |
---|
| 145 | group = ((JIDStatusGroup) selPath.getPathComponent(selPath.getPathCount() - 2)); |
---|
| 146 | jidStatus = ((PrimaryJIDStatus) o).getJIDPrimaryStatus(); |
---|
| 147 | } |
---|
| 148 | else if (o instanceof JIDStatus) |
---|
| 149 | { |
---|
| 150 | group = ((JIDStatusGroup) selPath.getPathComponent(selPath.getPathCount() - 3)); |
---|
| 151 | jidStatus = (JIDStatus)o; |
---|
| 152 | } |
---|
| 153 | else return; |
---|
| 154 | maybeShowPopup(e, jidStatus, group);//cde |
---|
| 155 | |
---|
| 156 | if (SwingUtilities.isLeftMouseButton(e)) |
---|
| 157 | { |
---|
| 158 | lastTreePath = selPath; |
---|
| 159 | //check if double or single mouseclick, needed |
---|
| 160 | // because double click= 2 single clicks |
---|
| 161 | if (timer.isRunning()) |
---|
| 162 | { |
---|
| 163 | timer.stop(); |
---|
| 164 | sendChat(jidStatus); |
---|
| 165 | } |
---|
| 166 | else |
---|
| 167 | { |
---|
| 168 | timer.restart(); |
---|
| 169 | } |
---|
| 170 | } |
---|
| 171 | } |
---|
| 172 | } |
---|
| 173 | } |
---|
| 174 | |
---|
| 175 | public void mouseReleased(MouseEvent e) |
---|
| 176 | { |
---|
| 177 | TreePath selPath = getPathForLocation(e.getX(), e.getY()); |
---|
| 178 | if (selPath != null) |
---|
| 179 | { |
---|
| 180 | Object o = selPath.getLastPathComponent(); |
---|
| 181 | if (o instanceof JIDStatusGroup) |
---|
| 182 | {//group |
---|
| 183 | maybeShowGroupPopup(e, (JIDStatusGroup) o); |
---|
| 184 | } |
---|
| 185 | if (o instanceof PrimaryJIDStatus) |
---|
| 186 | { |
---|
| 187 | JIDStatusGroup group = ((JIDStatusGroup) selPath.getPathComponent(selPath.getPathCount() - 2)); |
---|
| 188 | maybeShowPopup(e, ((PrimaryJIDStatus) o).getJIDPrimaryStatus(), group); |
---|
| 189 | } |
---|
| 190 | else if (o instanceof JIDStatus) |
---|
| 191 | { |
---|
| 192 | JIDStatusGroup group = ((JIDStatusGroup) selPath.getPathComponent(selPath.getPathCount() - 3)); |
---|
| 193 | maybeShowPopup(e, (JIDStatus) o, group); |
---|
| 194 | } |
---|
| 195 | } |
---|
| 196 | } |
---|
| 197 | |
---|
| 198 | public void mouseExited(MouseEvent e) |
---|
| 199 | { |
---|
| 200 | clearSelection();//weg als multi select? |
---|
| 201 | } |
---|
| 202 | }); |
---|
| 203 | |
---|
| 204 | addMouseMotionListener(new MouseMotionAdapter() |
---|
| 205 | { |
---|
| 206 | public void mouseMoved(MouseEvent e) |
---|
| 207 | { |
---|
| 208 | TreePath selPath = getPathForLocation(e.getX(), e.getY()); |
---|
| 209 | if (selPath != null) |
---|
| 210 | { |
---|
| 211 | //Object o = selPath.getLastPathComponent(); |
---|
| 212 | //if (o instanceof PrimaryJIDStatus || o instanceof JIDStatus) |
---|
| 213 | setSelectionPath(selPath); |
---|
| 214 | } |
---|
| 215 | } |
---|
| 216 | }); |
---|
| 217 | |
---|
| 218 | } |
---|
| 219 | |
---|
| 220 | public void updateLF() |
---|
| 221 | { |
---|
| 222 | SwingUtilities.updateComponentTreeUI(popupMenu); |
---|
| 223 | SwingUtilities.updateComponentTreeUI(groupPopupMenu); |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | private void createGroupPopupMenu() |
---|
| 227 | { |
---|
| 228 | groupPopupMenu = new JPopupMenu(); |
---|
| 229 | JMenuItem menuItem = null; |
---|
| 230 | menuItem = new JMenuItem(); |
---|
| 231 | I18N.setTextAndMnemonic("main.main.rostermenu.Remove",menuItem,true); |
---|
| 232 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 233 | { |
---|
| 234 | public void actionPerformed(ActionEvent e) |
---|
| 235 | { |
---|
| 236 | if (JOptionPane.showConfirmDialog(main, MessageFormat.format(I18N.gettext("main.popup.Really_remove_{0}?_All_JIDs_in_this_group_will_be_removed!"), new Object[] {currentGroup}), |
---|
| 237 | I18N.gettext("main.popup.Remove_Group"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) |
---|
| 238 | { |
---|
| 239 | for (Iterator i = currentJIDStatusGroup.iterator(); i.hasNext();) |
---|
| 240 | { |
---|
| 241 | PrimaryJIDStatus primary = (PrimaryJIDStatus) i.next(); |
---|
| 242 | if (primary.hasMultiple()) |
---|
| 243 | { |
---|
| 244 | for (Iterator j = primary.getOtherJidStatussen(); j.hasNext();) |
---|
| 245 | { |
---|
| 246 | groupRemove((JIDStatus) j.next()); |
---|
| 247 | } |
---|
| 248 | } |
---|
| 249 | groupRemove(primary.getJIDPrimaryStatus()); |
---|
| 250 | } |
---|
| 251 | } |
---|
| 252 | } |
---|
| 253 | |
---|
| 254 | private void groupRemove(JIDStatus jidStatus) |
---|
| 255 | { |
---|
| 256 | JID to = jidStatus.getJID(); |
---|
| 257 | if (jidStatus.groupCount() == 1) |
---|
| 258 | { |
---|
| 259 | if (JOptionPane.showConfirmDialog(main, |
---|
| 260 | MessageFormat.format(I18N.gettext( |
---|
| 261 | "main.popup.{0}_is_in_the_last_group,_remove_completely?") |
---|
| 262 | , new Object[] {to.toString()}) |
---|
| 263 | , I18N.gettext("main.main.rostermenu.Remove") |
---|
| 264 | , JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { |
---|
| 265 | IQXRoster roster = new IQXRoster(new RosterItem(to, null, "remove", null, null)); |
---|
| 266 | backend.send(new InfoQuery("set", roster)); |
---|
| 267 | } |
---|
| 268 | } |
---|
| 269 | else |
---|
| 270 | { |
---|
| 271 | List groups = jidStatus.getGroupsCopy(); |
---|
| 272 | groups.remove(currentGroup); |
---|
| 273 | IQXRoster roster = new IQXRoster(new RosterItem(to, jidStatus.getNick(), null, null, groups)); |
---|
| 274 | backend.send(new InfoQuery("set", roster)); |
---|
| 275 | } |
---|
| 276 | } |
---|
| 277 | }); |
---|
| 278 | |
---|
| 279 | groupPopupMenu.add(menuItem); |
---|
| 280 | menuItem = new JMenuItem(); |
---|
| 281 | I18N.setTextAndMnemonic("main.main.rostermenu.Rename",menuItem,true); |
---|
| 282 | menuItem.addActionListener(new ActionListener() |
---|
| 283 | { |
---|
| 284 | public void actionPerformed(ActionEvent e) |
---|
| 285 | { |
---|
| 286 | String groupName = JOptionPane.showInputDialog(main, MessageFormat.format(I18N.gettext("main.popup.Rename_{0}_to"),new Object[] {currentGroup})); |
---|
| 287 | if (groupName == null) return; |
---|
| 288 | for (Iterator i = currentJIDStatusGroup.iterator(); i.hasNext();) |
---|
| 289 | { |
---|
| 290 | PrimaryJIDStatus primary = (PrimaryJIDStatus) i.next(); |
---|
| 291 | if (primary.hasMultiple()) |
---|
| 292 | { |
---|
| 293 | for (Iterator j = primary.getOtherJidStatussen(); j.hasNext();) |
---|
| 294 | { |
---|
| 295 | renameGroup(groupName, (JIDStatus) j.next()); |
---|
| 296 | } |
---|
| 297 | } |
---|
| 298 | renameGroup(groupName, primary.getJIDPrimaryStatus()); |
---|
| 299 | } |
---|
| 300 | } |
---|
| 301 | |
---|
| 302 | private void renameGroup(String groupName, JIDStatus jidStatus) |
---|
| 303 | { |
---|
| 304 | List groups = jidStatus.getGroupsCopy(); |
---|
| 305 | groups.remove(currentGroup); |
---|
| 306 | groups.add(groupName); |
---|
| 307 | IQXRoster roster = new IQXRoster(new RosterItem(jidStatus.getJID(), jidStatus.getNick(), null, null, groups)); |
---|
| 308 | backend.send(new InfoQuery("set", roster)); |
---|
| 309 | } |
---|
| 310 | }); |
---|
| 311 | groupPopupMenu.add(menuItem); |
---|
| 312 | |
---|
| 313 | } |
---|
| 314 | |
---|
| 315 | public void createPopupMenu() |
---|
| 316 | { |
---|
| 317 | popupMenu = new JPopupMenu(); |
---|
| 318 | JMenuItem menuItem = null; |
---|
| 319 | JMenu subMenu = null; |
---|
| 320 | menuItem = new JMenuItem(); |
---|
| 321 | if(Preferences.getBoolean("jeti","rostermenuShowMessage",true)) |
---|
| 322 | { |
---|
| 323 | I18N.setTextAndMnemonic("main.main.rostermenu.Message",menuItem,true); |
---|
| 324 | menuItem.addActionListener(new ActionListener() |
---|
| 325 | { |
---|
| 326 | public void actionPerformed(ActionEvent e) |
---|
| 327 | { |
---|
| 328 | sendMessage(currentJIDStatus); |
---|
| 329 | } |
---|
| 330 | }); |
---|
| 331 | popupMenu.add(menuItem); |
---|
| 332 | } |
---|
| 333 | |
---|
| 334 | if(Preferences.getBoolean("jeti","rostermenuShowChat",true)) |
---|
| 335 | { |
---|
| 336 | menuItem = new JMenuItem(); |
---|
| 337 | I18N.setTextAndMnemonic("main.main.rostermenu.Chat",menuItem,true); |
---|
| 338 | menuItem.addActionListener(new ActionListener() |
---|
| 339 | { |
---|
| 340 | public void actionPerformed(ActionEvent e) |
---|
| 341 | { |
---|
| 342 | sendChat(currentJIDStatus); |
---|
| 343 | } |
---|
| 344 | }); |
---|
| 345 | popupMenu.add(menuItem); |
---|
| 346 | } |
---|
| 347 | |
---|
| 348 | if(Preferences.getBoolean("jeti","rostermenuSubscriptions",true)) |
---|
| 349 | { |
---|
| 350 | subMenu = new JMenu(I18N.gettext("main.main.rostermenu.Subscriptions")); |
---|
| 351 | menuItem = new JMenuItem(I18N.gettext("main.main.rostermenu.Subscribe_from")); |
---|
| 352 | menuItem = new JMenuItem(); |
---|
| 353 | I18N.setTextAndMnemonic("main.main.rostermenu.Subscribe_from",menuItem); |
---|
| 354 | menuItem.addActionListener(new ActionListener() |
---|
| 355 | { |
---|
| 356 | public void actionPerformed(ActionEvent e) |
---|
| 357 | { |
---|
| 358 | backend.send(new Presence(currentJIDStatus.getJID(), "subscribe")); |
---|
| 359 | } |
---|
| 360 | }); |
---|
| 361 | subMenu.add(menuItem); |
---|
| 362 | menuItem = new JMenuItem(I18N.gettext("main.main.rostermenu.Unsubscribe_from")); |
---|
| 363 | menuItem = new JMenuItem(); |
---|
| 364 | I18N.setTextAndMnemonic("main.main.rostermenu.Unsubscribe_from",menuItem); |
---|
| 365 | menuItem.addActionListener(new ActionListener() |
---|
| 366 | { |
---|
| 367 | public void actionPerformed(ActionEvent e) |
---|
| 368 | { |
---|
| 369 | backend.send(new Presence(currentJIDStatus.getJID(), "unsubscribe")); |
---|
| 370 | } |
---|
| 371 | }); |
---|
| 372 | subMenu.add(menuItem); |
---|
| 373 | popupMenu.add(subMenu); |
---|
| 374 | } |
---|
| 375 | if(Preferences.getBoolean("jeti","rostermenuRemove",true)) |
---|
| 376 | { |
---|
| 377 | menuItem = new JMenuItem(); |
---|
| 378 | I18N.setTextAndMnemonic("main.main.rostermenu.Remove",menuItem,true); |
---|
| 379 | menuItem.addActionListener(new ActionListener() |
---|
| 380 | { |
---|
| 381 | public void actionPerformed(ActionEvent e) |
---|
| 382 | { |
---|
| 383 | /** |
---|
| 384 | * @Author - Alexandre Correia - alexandrecorreia@celepar.pr.gov.br |
---|
| 385 | * @Date - 14/10/2008 |
---|
| 386 | * Criada a variavel String nickName para mostrar o nickname do usuario ao inves do UID |
---|
| 387 | * |
---|
| 388 | */ |
---|
| 389 | |
---|
| 390 | JID to = currentJIDStatus.getJID(); |
---|
| 391 | String nickName = currentJIDStatus.getNick(); |
---|
| 392 | if (JOptionPane.showConfirmDialog(main, MessageFormat.format(I18N.gettext("main.popup.Really_remove_{0}_from_all_groups_?"), |
---|
| 393 | new Object[] { nickName }),I18N.gettext("main.main.rostermenu.Remove"), |
---|
| 394 | JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) |
---|
| 395 | { |
---|
| 396 | IQXRoster roster = new IQXRoster(new RosterItem(to, null, "remove", null, null)); |
---|
| 397 | backend.send(new InfoQuery("set", roster)); |
---|
| 398 | } |
---|
| 399 | } |
---|
| 400 | }); |
---|
| 401 | popupMenu.add(menuItem); |
---|
| 402 | } |
---|
| 403 | if(Preferences.getBoolean("jeti","rostermenuRename",true)) |
---|
| 404 | { |
---|
| 405 | menuItem = new JMenuItem(); |
---|
| 406 | I18N.setTextAndMnemonic("main.main.rostermenu.Rename",menuItem,true); |
---|
| 407 | menuItem.addActionListener(new ActionListener() |
---|
| 408 | { |
---|
| 409 | public void actionPerformed(ActionEvent e) |
---|
| 410 | { |
---|
| 411 | String nick = JOptionPane.showInputDialog(main, MessageFormat.format(I18N.gettext("main.popup.Rename_{0}_to"),new Object[] {currentJIDStatus.getNick() })); |
---|
| 412 | if (nick == null) return; |
---|
| 413 | IQXRoster roster = new IQXRoster(new RosterItem(currentJIDStatus.getJID(), nick, null, null, currentJIDStatus.getGroupsCopy())); |
---|
| 414 | backend.send(new InfoQuery("set", roster)); |
---|
| 415 | } |
---|
| 416 | }); |
---|
| 417 | popupMenu.add(menuItem); |
---|
| 418 | } |
---|
| 419 | if(Preferences.getBoolean("jeti","rostermenuGroup",true)) |
---|
| 420 | { |
---|
| 421 | subMenu = new JMenu(); |
---|
| 422 | I18N.setTextAndMnemonic("main.main.rostermenu.Group",subMenu); |
---|
| 423 | menuItem = new JMenuItem(); |
---|
| 424 | I18N.setTextAndMnemonic("main.main.rostermenu.Change_Group", |
---|
| 425 | menuItem,true); |
---|
| 426 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 427 | { |
---|
| 428 | public void actionPerformed(ActionEvent e) |
---|
| 429 | { |
---|
| 430 | new GroupDialog(currentGroup, currentJIDStatus, backend).setVisible(true); |
---|
| 431 | } |
---|
| 432 | }); |
---|
| 433 | subMenu.add(menuItem); |
---|
| 434 | menuItem = new JMenuItem(); |
---|
| 435 | I18N.setTextAndMnemonic("main.main.rostermenu.Add_to_Group", |
---|
| 436 | menuItem, true); |
---|
| 437 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 438 | { |
---|
| 439 | public void actionPerformed(ActionEvent e) |
---|
| 440 | { |
---|
| 441 | new GroupDialog(currentJIDStatus, backend).setVisible(true); |
---|
| 442 | } |
---|
| 443 | }); |
---|
| 444 | subMenu.add(menuItem); |
---|
| 445 | menuItem = new JMenuItem(); |
---|
| 446 | I18N.setTextAndMnemonic("main.main.rostermenu.Remove_from_group", |
---|
| 447 | menuItem,true); |
---|
| 448 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 449 | { |
---|
| 450 | public void actionPerformed(ActionEvent e) |
---|
| 451 | { |
---|
| 452 | JID to = currentJIDStatus.getJID(); |
---|
| 453 | if (currentJIDStatus.groupCount() == 1) |
---|
| 454 | { |
---|
| 455 | if (JOptionPane.showConfirmDialog(main |
---|
| 456 | , MessageFormat.format( |
---|
| 457 | I18N.gettext("main.popup.{0}_is_in_the_last_group,_remove_completely?") |
---|
| 458 | ,new Object[]{to.toString() }) |
---|
| 459 | , I18N.gettext("main.main.rostermenu.Remove") |
---|
| 460 | , JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) |
---|
| 461 | { |
---|
| 462 | IQXRoster roster = new IQXRoster(new RosterItem(to, null, "remove", null, null)); |
---|
| 463 | backend.send(new InfoQuery("set", roster)); |
---|
| 464 | } |
---|
| 465 | } |
---|
| 466 | else |
---|
| 467 | { |
---|
| 468 | List groups = currentJIDStatus.getGroupsCopy(); |
---|
| 469 | groups.remove(currentGroup); |
---|
| 470 | IQXRoster roster = new IQXRoster(new RosterItem(to, currentJIDStatus.getNick(), null, null, groups)); |
---|
| 471 | backend.send(new InfoQuery("set", roster)); |
---|
| 472 | } |
---|
| 473 | } |
---|
| 474 | }); |
---|
| 475 | subMenu.add(menuItem); |
---|
| 476 | popupMenu.add(subMenu); |
---|
| 477 | } |
---|
| 478 | if (onlineTree) { |
---|
| 479 | if(Preferences.getBoolean("jeti","rostermenuLocalTime",true) |
---|
| 480 | && !Preferences.getBoolean("jeti", "privacy", false)) |
---|
| 481 | { |
---|
| 482 | menuItem = new JMenuItem(); |
---|
| 483 | I18N.setTextAndMnemonic("main.main.rostermenu.Local_Time", |
---|
| 484 | menuItem, true); |
---|
| 485 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 486 | { |
---|
| 487 | public void actionPerformed(ActionEvent e) |
---|
| 488 | { |
---|
| 489 | backend.send(new InfoQuery(currentJIDStatus.getCompleteJID(), "get", new IQTime())); |
---|
| 490 | |
---|
| 491 | } |
---|
| 492 | }); |
---|
| 493 | |
---|
| 494 | popupMenu.add(menuItem); |
---|
| 495 | } |
---|
| 496 | if(Preferences.getBoolean("jeti","rostermenuLocalVersion",true) |
---|
| 497 | && !Preferences.getBoolean("jeti", "privacy", false)) |
---|
| 498 | { |
---|
| 499 | menuItem = new JMenuItem(); |
---|
| 500 | I18N.setTextAndMnemonic("main.main.rostermenu.Local_Version", |
---|
| 501 | menuItem, true); |
---|
| 502 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 503 | { |
---|
| 504 | public void actionPerformed(ActionEvent e) |
---|
| 505 | { |
---|
| 506 | backend.send(new InfoQuery(currentJIDStatus.getCompleteJID(), "get", new IQVersion())); |
---|
| 507 | } |
---|
| 508 | }); |
---|
| 509 | popupMenu.add(menuItem); |
---|
| 510 | } |
---|
| 511 | } |
---|
| 512 | else |
---|
| 513 | { |
---|
| 514 | if(Preferences.getBoolean("jeti","rostermenuLastSeen",true)) |
---|
| 515 | { |
---|
| 516 | menuItem = new JMenuItem(); |
---|
| 517 | I18N.setTextAndMnemonic("main.main.rostermenu.Last_Seen",menuItem,true); |
---|
| 518 | menuItem.addActionListener(new java.awt.event.ActionListener() |
---|
| 519 | { |
---|
| 520 | public void actionPerformed(ActionEvent e) |
---|
| 521 | { |
---|
| 522 | backend.send(new InfoQuery(currentJIDStatus.getJID(), "get", new IQLast())); |
---|
| 523 | } |
---|
| 524 | }); |
---|
| 525 | popupMenu.add(menuItem); |
---|
| 526 | } |
---|
| 527 | } |
---|
| 528 | if(Preferences.getBoolean("jeti","rostermenuInvisible",true)) |
---|
| 529 | { |
---|
| 530 | final JMenuItem menuItem3 = new JMenuItem(); |
---|
| 531 | I18N.setTextAndMnemonic("main.main.rostermenu.Set_Invisible",menuItem3); |
---|
| 532 | menuItem3.addActionListener(new java.awt.event.ActionListener() |
---|
| 533 | { |
---|
| 534 | public void actionPerformed(ActionEvent e) |
---|
| 535 | { |
---|
| 536 | if(menuItem3.getText().equals(I18N.gettext("main.main.rostermenu.Set_Invisible"))) |
---|
| 537 | { |
---|
| 538 | I18N.setTextAndMnemonic("main.main.rostermenu.Set_Visible",menuItem3); |
---|
| 539 | backend.send(new Presence(currentJIDStatus.getJID(), "invisible")); |
---|
| 540 | } |
---|
| 541 | else |
---|
| 542 | { |
---|
| 543 | I18N.setTextAndMnemonic("main.main.rostermenu.Set_Invisible",menuItem3); |
---|
| 544 | backend.send(new Presence(currentJIDStatus.getJID(),"available")); |
---|
| 545 | } |
---|
| 546 | } |
---|
| 547 | }); |
---|
| 548 | popupMenu.add(menuItem3); |
---|
| 549 | } |
---|
| 550 | if (menuItems != null) |
---|
| 551 | { |
---|
| 552 | for (Iterator i = menuItems.entrySet().iterator(); i.hasNext();) |
---|
| 553 | { |
---|
| 554 | Map.Entry entry = (Map.Entry) i.next(); |
---|
| 555 | JMenuItem item = new JMenuItem((String) entry.getKey()); |
---|
| 556 | final RosterMenuListener listener = (RosterMenuListener) entry.getValue(); |
---|
| 557 | item.addActionListener(new java.awt.event.ActionListener() |
---|
| 558 | { |
---|
| 559 | public void actionPerformed(ActionEvent e) |
---|
| 560 | { |
---|
| 561 | listener.actionPerformed(currentJIDStatus, currentJIDStatusGroup2); |
---|
| 562 | } |
---|
| 563 | }); |
---|
| 564 | popupMenu.add(item); |
---|
| 565 | } |
---|
| 566 | } |
---|
| 567 | } |
---|
| 568 | |
---|
| 569 | public void addToMenu(String name, RosterMenuListener listener) |
---|
| 570 | { |
---|
| 571 | if (menuItems == null) menuItems = new HashMap(10); |
---|
| 572 | menuItems.put(name, listener); |
---|
| 573 | if (popupMenu != null) createPopupMenu(); |
---|
| 574 | } |
---|
| 575 | |
---|
| 576 | public void removeFromMenu(String name) |
---|
| 577 | { |
---|
| 578 | if (menuItems == null) return; |
---|
| 579 | menuItems.remove(name); |
---|
| 580 | if (menuItems.isEmpty()) menuItems = null; |
---|
| 581 | if (popupMenu != null) createPopupMenu(); |
---|
| 582 | } |
---|
| 583 | |
---|
| 584 | public List getOpenGroups() |
---|
| 585 | { |
---|
| 586 | List tempList = new LinkedList(); |
---|
| 587 | JIDStatusTree tree = ((JIDStatusTree) getModel().getRoot()); |
---|
| 588 | |
---|
| 589 | if (tree == null) |
---|
| 590 | return null; |
---|
| 591 | |
---|
| 592 | for (int i = 0; i < tree.getSize(); i++) |
---|
| 593 | { |
---|
| 594 | TreePath path = new TreePath(new Object[] { tree, tree.get(i)}); |
---|
| 595 | if (isExpanded(path)) |
---|
| 596 | { |
---|
| 597 | tempList.add(tree.get(i).toString()); |
---|
| 598 | } |
---|
| 599 | } |
---|
| 600 | |
---|
| 601 | return tempList; |
---|
| 602 | |
---|
| 603 | } |
---|
| 604 | |
---|
| 605 | public void openGroups(JetiPrivateRosterExtension extension) |
---|
| 606 | { |
---|
| 607 | String[] groups = extension.getOpenGroups(); |
---|
| 608 | JIDStatusTree tree = ((JIDStatusTree) getModel().getRoot()); |
---|
| 609 | if (groups == null) return; |
---|
| 610 | for (int i = 0; i < groups.length; i++) |
---|
| 611 | { |
---|
| 612 | if(tree.existGroup(groups[i])) |
---|
| 613 | { |
---|
| 614 | TreePath path = new TreePath(new Object[] { tree, tree.getGroup(groups[i])}); |
---|
| 615 | if (treeExpander != null) { |
---|
| 616 | treeExpander.expand(path); |
---|
| 617 | } else { |
---|
| 618 | expandPath(path); |
---|
| 619 | } |
---|
| 620 | } |
---|
| 621 | } |
---|
| 622 | |
---|
| 623 | } |
---|
| 624 | |
---|
| 625 | private void sendMessage(JIDStatus jidStatus) |
---|
| 626 | { |
---|
| 627 | new SendMessage(backend, jidStatus.getJID(), jidStatus.getNick()).setVisible(true); |
---|
| 628 | } |
---|
| 629 | |
---|
| 630 | private void sendChat(JIDStatus jidStatus) |
---|
| 631 | { |
---|
| 632 | main.chat(jidStatus); |
---|
| 633 | } |
---|
| 634 | |
---|
| 635 | private void maybeShowPopup(MouseEvent e, JIDStatus jidStatus, JIDStatusGroup group) |
---|
| 636 | { |
---|
| 637 | if (e.isPopupTrigger()) |
---|
| 638 | { |
---|
| 639 | currentJIDStatus = jidStatus; |
---|
| 640 | currentGroup = group.getName(); |
---|
| 641 | currentJIDStatusGroup2 = group; |
---|
| 642 | popupMenu.show(e.getComponent(), e.getX(), e.getY()); |
---|
| 643 | } |
---|
| 644 | } |
---|
| 645 | |
---|
| 646 | private void maybeShowGroupPopup(MouseEvent e, JIDStatusGroup jidStatusGroup) |
---|
| 647 | { |
---|
| 648 | if (e.isPopupTrigger()) |
---|
| 649 | { |
---|
| 650 | currentJIDStatusGroup = jidStatusGroup; |
---|
| 651 | currentGroup = jidStatusGroup.getName(); |
---|
| 652 | groupPopupMenu.show(e.getComponent(), e.getX(), e.getY()); |
---|
| 653 | } |
---|
| 654 | } |
---|
| 655 | |
---|
| 656 | JIDStatus tooltipjids; |
---|
| 657 | |
---|
| 658 | public String getToolTipText(MouseEvent ev) |
---|
| 659 | { |
---|
| 660 | if ( ev == null) return null; |
---|
| 661 | TreePath path = getPathForLocation(ev.getX(), ev.getY()); |
---|
| 662 | if ( path != null ) |
---|
| 663 | { |
---|
| 664 | JIDStatus jidStatus = null; |
---|
| 665 | Object o = path.getLastPathComponent(); |
---|
| 666 | if (o instanceof PrimaryJIDStatus) |
---|
| 667 | { |
---|
| 668 | jidStatus = ((PrimaryJIDStatus) o).getJIDPrimaryStatus(); |
---|
| 669 | |
---|
| 670 | } |
---|
| 671 | else if (o instanceof JIDStatus) |
---|
| 672 | { |
---|
| 673 | jidStatus = ((JIDStatus) o); |
---|
| 674 | } |
---|
| 675 | else |
---|
| 676 | { |
---|
| 677 | return null; |
---|
| 678 | } |
---|
| 679 | |
---|
| 680 | String statusMsg; |
---|
| 681 | |
---|
| 682 | if (jidStatus.getStatus() != null) |
---|
| 683 | { |
---|
| 684 | statusMsg = jidStatus.getStatus(); |
---|
| 685 | } |
---|
| 686 | else |
---|
| 687 | { |
---|
| 688 | statusMsg = ""; |
---|
| 689 | } |
---|
| 690 | |
---|
| 691 | String waitingStatus = jidStatus.getWaiting(); |
---|
| 692 | |
---|
| 693 | if ( jidStatus.getWaiting() != null ) |
---|
| 694 | { |
---|
| 695 | waitingStatus = I18N.gettext("main.main.roster.Waiting_Status") + " " + jidStatus.getWaiting(); |
---|
| 696 | } |
---|
| 697 | else |
---|
| 698 | { |
---|
| 699 | waitingStatus = ""; |
---|
| 700 | } |
---|
| 701 | |
---|
| 702 | String htmlReturn = ""; |
---|
| 703 | htmlReturn = "<html>"; |
---|
| 704 | htmlReturn += "<table border='0' cellpadding='0' cellspacing='0' bgcolor='#ffffff' width='300'>"; |
---|
| 705 | htmlReturn += "<tr>"; |
---|
| 706 | htmlReturn += "<td valign='top' style='margin-left:5px'>"; |
---|
| 707 | htmlReturn += "<b>Nick:</b> " + jidStatus.getNick() + "<br/>"; |
---|
| 708 | htmlReturn += "<b>" + I18N.gettext("main.main.roster.Status") + "</b> " + Presence.toLongShow(jidStatus.getShow()) + "<br/>"; |
---|
| 709 | htmlReturn += "<b>" + I18N.gettext("main.main.statusmenu.Status_message") + "</b> " + statusMsg + "<br/>"; |
---|
| 710 | htmlReturn += "<b>" + I18N.gettext("main.main.roster.Subscription") + "</b> " + jidStatus.getSubscription() + "<br/>"; |
---|
| 711 | htmlReturn += "<b>" + waitingStatus + "<b/>"; |
---|
| 712 | htmlReturn += "</td>"; |
---|
| 713 | htmlReturn += "</tr>"; |
---|
| 714 | htmlReturn += "<tr>"; |
---|
| 715 | htmlReturn += "<td align='right'><font style='font-size:10pt;font-weight:bold'>" + nu.fw.jeti.applet.Jeti.NAMECOMPANY + "</td>"; |
---|
| 716 | htmlReturn += "</tr>"; |
---|
| 717 | htmlReturn += "</table>"; |
---|
| 718 | htmlReturn += "</html>"; |
---|
| 719 | |
---|
| 720 | return htmlReturn; |
---|
| 721 | } |
---|
| 722 | return null; |
---|
| 723 | } |
---|
| 724 | |
---|
| 725 | public JToolTip createToolTip() |
---|
| 726 | { |
---|
| 727 | return super.createToolTip(); |
---|
| 728 | } |
---|
| 729 | |
---|
| 730 | class MyRenderer extends DefaultTreeCellRenderer //implements TreeCellRenderer |
---|
| 731 | { |
---|
| 732 | //TODO setpreferred size on mac (not on the render) to fix not 0 |
---|
| 733 | private JLabel renderer; |
---|
| 734 | private Component fill = Box.createRigidArea(new Dimension(0, 0)); |
---|
| 735 | |
---|
| 736 | public MyRenderer() |
---|
| 737 | { |
---|
| 738 | |
---|
| 739 | renderer = new JLabel(); |
---|
| 740 | renderer.setFont(UIManager.getFont("Tree.font")); |
---|
| 741 | } |
---|
| 742 | |
---|
| 743 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) |
---|
| 744 | { |
---|
| 745 | |
---|
| 746 | String text = value.toString(); |
---|
| 747 | renderer.setText(text); |
---|
| 748 | |
---|
| 749 | if (sel) |
---|
| 750 | { |
---|
| 751 | renderer.setOpaque(true); |
---|
| 752 | renderer.setForeground(UIManager.getColor("Tree.selectionForeground")); |
---|
| 753 | renderer.setBackground(UIManager.getColor("Tree.selectionBackground")); |
---|
| 754 | } |
---|
| 755 | else |
---|
| 756 | { |
---|
| 757 | renderer.setForeground(UIManager.getColor("Tree.textForeground")); |
---|
| 758 | renderer.setOpaque(Preferences.getBoolean("jeti", "bmw", true)); |
---|
| 759 | renderer.setBackground(UIManager.getColor("Tree.background")); |
---|
| 760 | //renderer.setOpaque(false); |
---|
| 761 | } |
---|
| 762 | |
---|
| 763 | if (leaf) |
---|
| 764 | { |
---|
| 765 | return (makeComponent((JIDStatus) value)); |
---|
| 766 | } |
---|
| 767 | |
---|
| 768 | if (value instanceof PrimaryJIDStatus) |
---|
| 769 | { |
---|
| 770 | PrimaryJIDStatus ps = (PrimaryJIDStatus) value; |
---|
| 771 | JIDStatus jidsStatus = ps.getJIDPrimaryStatus(); |
---|
| 772 | if (ps.hasMultiple()) |
---|
| 773 | { |
---|
| 774 | if (onlineTree) |
---|
| 775 | { |
---|
| 776 | if (ps.multipleJIDstatusOnline()) |
---|
| 777 | renderer.setForeground(new Color(0, 0, 190)); |
---|
| 778 | return makeComponent(jidsStatus); |
---|
| 779 | } |
---|
| 780 | if (ps.isAJIDstatusOffline()) |
---|
| 781 | { |
---|
| 782 | // if offline tree and a jidStatus in primary is offline |
---|
| 783 | // show |
---|
| 784 | renderer.setIcon(StatusIcons.getImageIcon("multiple")); |
---|
| 785 | return renderer; |
---|
| 786 | } |
---|
| 787 | return fill; |
---|
| 788 | } |
---|
| 789 | return makeComponent(jidsStatus); |
---|
| 790 | } |
---|
| 791 | else if (value instanceof JIDStatusGroup) |
---|
| 792 | { |
---|
| 793 | JIDStatusGroup group = (JIDStatusGroup) value; |
---|
| 794 | |
---|
| 795 | /*if ( onlineTree ) |
---|
| 796 | { |
---|
| 797 | if (group.getOnlines() == 0) |
---|
| 798 | return fill;*/ |
---|
| 799 | |
---|
| 800 | text = group.toString() + " ( " + group.getOnlines() + " / " + group.size() + " ) "; |
---|
| 801 | renderer.setText(text); |
---|
| 802 | //} |
---|
| 803 | |
---|
| 804 | if ( expanded ) |
---|
| 805 | renderer.setIcon(StatusIcons.getImageIcon("arrowDown")); |
---|
| 806 | else |
---|
| 807 | renderer.setIcon(StatusIcons.getImageIcon("arrowUp")); |
---|
| 808 | } |
---|
| 809 | return renderer; |
---|
| 810 | } |
---|
| 811 | |
---|
| 812 | private Component makeComponent(JIDStatus jidStatus) |
---|
| 813 | { |
---|
| 814 | /** |
---|
| 815 | * Monta a lista de Conectado e Desconectado |
---|
| 816 | * Esta parte esta comentada para montar apenas um ramo com todos os grupos e seus usuarios ( online / offline ) |
---|
| 817 | */ |
---|
| 818 | |
---|
| 819 | /*if (jidStatus.isOnline()) |
---|
| 820 | { |
---|
| 821 | if (!onlineTree) |
---|
| 822 | return fill; // leeg want offline tree |
---|
| 823 | renderer.setIcon(StatusIcons.getStatusIcon(jidStatus)); |
---|
| 824 | } |
---|
| 825 | else |
---|
| 826 | { |
---|
| 827 | if (onlineTree) |
---|
| 828 | return fill; //leeg want online tree |
---|
| 829 | renderer.setIcon(StatusIcons.getStatusIcon(jidStatus)); |
---|
| 830 | }*/ |
---|
| 831 | |
---|
| 832 | renderer.setIcon(StatusIcons.getStatusIcon(jidStatus)); |
---|
| 833 | return renderer; |
---|
| 834 | } |
---|
| 835 | } |
---|
| 836 | |
---|
| 837 | |
---|
| 838 | class MacRenderer implements TreeCellRenderer |
---|
| 839 | { |
---|
| 840 | //special render for Mac because it doesn't support 0 sized components in the tree |
---|
| 841 | private JLabel renderer; |
---|
| 842 | |
---|
| 843 | public MacRenderer() |
---|
| 844 | { |
---|
| 845 | renderer = new JLabel(); |
---|
| 846 | renderer.setFont(UIManager.getFont("Tree.font")); |
---|
| 847 | } |
---|
| 848 | |
---|
| 849 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) |
---|
| 850 | { |
---|
| 851 | renderer.setText(value.toString()); |
---|
| 852 | if (sel) |
---|
| 853 | { |
---|
| 854 | renderer.setOpaque(true); |
---|
| 855 | renderer.setForeground(UIManager |
---|
| 856 | .getColor("Tree.selectionForeground")); |
---|
| 857 | renderer.setBackground(UIManager.getColor("Tree.selectionBackground")); |
---|
| 858 | } else |
---|
| 859 | { |
---|
| 860 | renderer.setForeground(UIManager.getColor("Tree.textForeground")); |
---|
| 861 | renderer.setOpaque(Preferences.getBoolean("jeti", "bmw", true)); |
---|
| 862 | renderer.setBackground(UIManager.getColor("Tree.background")); |
---|
| 863 | } |
---|
| 864 | if (leaf) { return (makeComponent((JIDStatus) value)); } |
---|
| 865 | if (value instanceof PrimaryJIDStatus) |
---|
| 866 | { |
---|
| 867 | PrimaryJIDStatus ps = (PrimaryJIDStatus) value; |
---|
| 868 | JIDStatus jidsStatus = ps.getJIDPrimaryStatus(); |
---|
| 869 | if (ps.hasMultiple()) |
---|
| 870 | { |
---|
| 871 | if (onlineTree) { |
---|
| 872 | if (ps.multipleJIDstatusOnline()) { |
---|
| 873 | renderer.setForeground(new Color(0, 0, 190)); |
---|
| 874 | } |
---|
| 875 | return makeComponent(jidsStatus); |
---|
| 876 | } |
---|
| 877 | if (ps.isAJIDstatusOffline()) |
---|
| 878 | {//if offline tree and a jidStatus in primary is offline |
---|
| 879 | // show |
---|
| 880 | renderer.setIcon(StatusIcons.getImageIcon("multiple")); |
---|
| 881 | } |
---|
| 882 | return renderer; |
---|
| 883 | } |
---|
| 884 | return makeComponent(jidsStatus); |
---|
| 885 | } |
---|
| 886 | else if (value instanceof JIDStatusGroup) |
---|
| 887 | { |
---|
| 888 | JIDStatusGroup group = (JIDStatusGroup) value; |
---|
| 889 | if (onlineTree) { |
---|
| 890 | renderer.setText(group.toString() + " (" |
---|
| 891 | + group.getOnlines() + ")"); |
---|
| 892 | } |
---|
| 893 | if (expanded) { |
---|
| 894 | renderer.setIcon(StatusIcons.getImageIcon("arrowDown")); |
---|
| 895 | } else { |
---|
| 896 | renderer.setIcon(StatusIcons.getImageIcon("arrowUp")); |
---|
| 897 | } |
---|
| 898 | } |
---|
| 899 | return renderer; |
---|
| 900 | } |
---|
| 901 | |
---|
| 902 | private Component makeComponent(JIDStatus jidStatus) |
---|
| 903 | { |
---|
| 904 | int show; |
---|
| 905 | if (jidStatus.isOnline()) { |
---|
| 906 | show = jidStatus.getShow(); |
---|
| 907 | } else { |
---|
| 908 | show = Presence.UNAVAILABLE; |
---|
| 909 | } |
---|
| 910 | renderer.setIcon(StatusIcons.getStatusIcon(show, |
---|
| 911 | jidStatus.getType())); |
---|
| 912 | return renderer; |
---|
| 913 | } |
---|
| 914 | } |
---|
| 915 | |
---|
| 916 | } |
---|
| 917 | /* |
---|
| 918 | * Overrides for emacs |
---|
| 919 | * Local variables: |
---|
| 920 | * tab-width: 4 |
---|
| 921 | * End: |
---|
| 922 | */ |
---|