001 /* 002 Copyright (C) 2003 Adam Olsen 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU General Public License as published by 006 the Free Software Foundation; either version 1, or (at your option) 007 any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details. 013 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 017 */ 018 019 package com.valhalla.jbother; 020 021 import java.awt.*; 022 import java.awt.event.*; 023 import java.util.*; 024 import javax.swing.*; 025 026 import org.jivesoftware.smack.*; 027 import org.jivesoftware.smack.packet.XMPPError; 028 029 import com.valhalla.gui.*; 030 import com.valhalla.jbother.*; 031 import com.valhalla.jbother.jabber.BuddyStatus; 032 033 /** 034 * Displays a dialog allowing to you add or modify a buddy. 035 * It displays their JID, Alias, and group 036 * 037 * @author Adam Olsen 038 * @version 1.0 039 */ 040 public class AddBuddyDialog extends JDialog 041 { 042 private ResourceBundle resources = ResourceBundle.getBundle( "JBotherBundle", Locale.getDefault() ); 043 044 private JComboBox buddyGroups; 045 private JTextField buddyIDBox = new JTextField( 15 ); 046 private JTextField buddyAliasBox = new JTextField( 15 ); 047 private JTextField newGroupBox; 048 private JPanel container = new JPanel(); 049 050 private RosterEntry entry; 051 private String currentGroup = ""; 052 053 //the buttons 054 private JButton okButton = new JButton( resources.getString( "okButton" ) ); 055 private JButton cancelButton = new JButton( resources.getString( "cancelButton" ) ); 056 057 //this part is for laying out the rows for the dialog 058 private int row = 0; 059 private GridBagLayout grid = new GridBagLayout(); 060 private GridBagConstraints c = new GridBagConstraints(); 061 private boolean modify = false; 062 063 /** 064 * The add buddy constructor 065 */ 066 public AddBuddyDialog() 067 { 068 super( BuddyList.getInstance(), "Add/Modify Buddy", false ); 069 setTitle( resources.getString( "addBuddyDialogTitle" ) ); 070 071 this.initComponents(); 072 container.setBorder( BorderFactory.createEmptyBorder( 5, 25, 5, 25 ) ); 073 container.setLayout( new BoxLayout( container, BoxLayout.Y_AXIS ) ); 074 075 JLabel newBuddyLabel = new JLabel( resources.getString( "addBuddyDialogTitle" ) ); 076 newBuddyLabel.setBorder( BorderFactory.createEmptyBorder( 5, 0, 5, 0 ) ); 077 newBuddyLabel.setAlignmentX( Container.CENTER_ALIGNMENT ); 078 container.add( newBuddyLabel ); 079 080 JPanel newBuddyPanel = new JPanel(); 081 newBuddyPanel.setLayout( grid ); 082 083 createInputBox( newBuddyPanel, grid, resources.getString( "buddyId" ) + ":", buddyIDBox ); 084 createInputBox( newBuddyPanel, grid, resources.getString( "alias" ) + ":", buddyAliasBox ); 085 createInputBox( newBuddyPanel, grid, resources.getString( "buddyGroup" ) + ":", buddyGroups ); 086 createInputBox( newBuddyPanel, grid, resources.getString( "newGroup" ) + ":", newGroupBox ); 087 088 container.add( newBuddyPanel ); 089 090 //add the buttons 091 JPanel buttonPanel = new JPanel(); 092 buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.X_AXIS ) ); 093 buttonPanel.setBorder( BorderFactory.createEmptyBorder( 5, 0, 5, 0 ) ); 094 buttonPanel.add( okButton ); 095 buttonPanel.add( cancelButton ); 096 097 container.add( buttonPanel ); 098 099 DialogTracker.addDialog( this, true, true ); 100 setResizable( false ); 101 102 pack(); 103 setLocationRelativeTo( null ); 104 105 } 106 107 /** 108 * Destroys the dialog 109 */ 110 public void delete() 111 { 112 DialogTracker.removeDialog( this ); 113 } 114 115 /** 116 * The modify buddy constructor 117 * @param entry the entry to modify 118 */ 119 public void setBuddy( RosterEntry entry ) 120 { 121 this.entry = entry; 122 this.buddyIDBox.setText( entry.getUser() ); 123 this.buddyIDBox.setEnabled( false ); 124 this.modify= true; 125 this.buddyAliasBox.setText( entry.getName() ); 126 127 String currentGroup = ""; 128 129 Iterator iterator = entry.getGroups(); 130 while( iterator.hasNext() ) 131 { 132 RosterGroup group = (RosterGroup)iterator.next(); 133 currentGroup = group.getName(); 134 } 135 136 if( !currentGroup.equals( "" ) ) this.currentGroup = currentGroup; 137 138 139 //buddyGroups = new JComboBox( getRosterGroups() ); 140 buddyGroups.setModel( new DefaultComboBoxModel( getRosterGroups() ) ); 141 142 validate(); 143 } 144 145 /** 146 * Called by the cancel button - destroys the dialog 147 */ 148 private void cancelButtonHandler() 149 { 150 DialogTracker.removeDialog( this ); 151 } 152 153 /** 154 * Sets the JID in the dialog 155 * @param id the JID 156 */ 157 public void setBuddyId( String id ) 158 { 159 buddyIDBox.setText( id ); 160 validate(); 161 } 162 163 /** 164 * Sets up visual components 165 */ 166 private void initComponents() 167 { 168 setContentPane( container ); 169 buddyGroups = new JComboBox( getRosterGroups() ); 170 newGroupBox = new JTextField( 15 ); 171 newGroupBox.setText( resources.getString( "newGroup" ) ); 172 newGroupBox.setEnabled( false ); 173 174 //add the handlers 175 cancelButton.addActionListener( new ActionHandler() ); 176 okButton.addActionListener( new ActionHandler() ); 177 newGroupBox.addActionListener( new ActionHandler() ); 178 buddyAliasBox.addActionListener( new ActionHandler() ); 179 buddyGroups.addItemListener( new ItemListener() 180 { 181 public void itemStateChanged( ItemEvent e ) 182 { 183 String item = (String)e.getItem(); 184 if( item.equals( resources.getString( "newGroup" ) ) ) 185 { 186 newGroupBox.setEnabled( true ); 187 newGroupBox.setText( "" ); 188 newGroupBox.grabFocus(); 189 } 190 else { 191 newGroupBox.setEnabled( false ); 192 if( newGroupBox.getText().equals( "" ) ) newGroupBox.setText( resources.getString( "newGroup" ) ); 193 } 194 } 195 } ); 196 197 addWindowListener( new WindowAdapter() 198 { 199 public void windowClosing( WindowEvent e ) 200 { 201 cancelButtonHandler(); 202 } 203 } ); 204 } 205 206 /** 207 * assures that all required information has been filled out in the dialog 208 */ 209 private boolean checkInformation() 210 { 211 if( buddyIDBox.getText().equals( "" ) ) 212 return Standard.warningMessage( this, resources.getString( "addBuddyDialogTitle" ), resources.getString( "noIdError" ) ); 213 214 if( buddyAliasBox.getText().equals( "" ) ) 215 return Standard.warningMessage( this, resources.getString( "addBuddyDialogTitle" ), resources.getString( "noAliasError" ) ); 216 217 if( buddyGroups.getSelectedItem().equals( resources.getString( "newGroup" ) ) ) 218 { 219 if( newGroupBox.getText().equals( "" ) || newGroupBox.getText().equals( resources.getString( "newGroup" ) ) ) 220 return Standard.warningMessage( this, resources.getString( "addBuddyDialogTitle" ), 221 resources.getString( "newGroupError" ) ); 222 } 223 224 return true; 225 } 226 227 /** 228 * Called by OK button - checks information and adds the buddy 229 */ 230 private void okButtonHandler() 231 { 232 if( checkInformation() ) 233 { 234 String buddyGroup = (String)buddyGroups.getSelectedItem(); 235 if( buddyGroup.equals( resources.getString( "newGroup" ) ) ) buddyGroup = newGroupBox.getText(); 236 if( buddyGroup.equals( resources.getString( "none" ) ) ) buddyGroup = null; 237 238 addBuddy( buddyGroup, buddyAliasBox.getText(), buddyIDBox.getText() ); 239 } 240 } 241 242 /** 243 * Handles all button events 244 * @author Adam Olsen 245 * @version 1.0 246 */ 247 class ActionHandler implements ActionListener 248 { 249 public void actionPerformed( ActionEvent e ) 250 { 251 if( e.getSource() != cancelButton ) okButtonHandler(); 252 else cancelButtonHandler(); 253 } 254 } 255 256 /** 257 * Creates an input box with a corresponding label 258 * @param container the container to add the input box to 259 * @param grid the GridBagLayout to use 260 * @param label the label to use 261 * @param box the input box to use 262 */ 263 private void createInputBox( Container container, GridBagLayout grid, String label, Container box ) 264 { 265 JLabel labelBox = new JLabel( label + " " ); 266 267 c.gridy = row++; 268 c.gridx = 0; 269 c.anchor = GridBagConstraints.EAST; 270 grid.setConstraints( labelBox, c ); 271 container.add( labelBox ); 272 273 c.gridx = 1; 274 c.anchor = GridBagConstraints.WEST; 275 grid.setConstraints( box, c ); 276 container.add( box ); 277 } 278 279 /** 280 * Gets the different available RosterGroups 281 * @return an array of strings representing the RosterGroups 282 */ 283 private String[] getRosterGroups() 284 { 285 Roster roster = BuddyList.getInstance().getConnection().getRoster(); 286 String rosterGroups[] = new String[roster.getGroupCount() + 2]; 287 288 int i = 0; 289 290 if( ( !currentGroup.equals( "" ) ) ) 291 { 292 rosterGroups[i] = currentGroup; 293 i++; 294 } 295 296 rosterGroups[i++] = resources.getString( "none" ); 297 rosterGroups[i++] = resources.getString( "newGroup" ); 298 299 Iterator iterator = roster.getGroups(); 300 while( iterator.hasNext() ) 301 { 302 RosterGroup rosterGroup = (RosterGroup)iterator.next(); 303 if( ( currentGroup.equals( "" ) ) || ( !rosterGroup.getName().equals( currentGroup ) ) ) 304 { 305 rosterGroups[i] = rosterGroup.getName(); 306 i++; 307 } 308 } 309 310 return rosterGroups; 311 } 312 313 /** 314 * Runs the add buddy thread and adds or modifies a buddy in the Roster 315 * @param groupName the group to put the buddy in 316 * @param buddyAlias the alias of the buddy 317 * @param buddyId the buddy's JID 318 */ 319 private void addBuddy( String groupName, String buddyAlias, String buddyId ) 320 { 321 Roster buddyGroups = BuddyList.getInstance().getConnection().getRoster(); 322 323 WaitDialog wait = new WaitDialog( resources.getString( "pleaseWait" ) ); 324 wait.setVisible( true ); 325 setVisible( false ); 326 327 Thread thread = new Thread( new AddBuddyThread( wait, groupName, buddyAlias, buddyId, this ) ); 328 thread.start(); 329 } 330 331 /** 332 * Actually adds the buddy to the Roster 333 * @author Adam Olsen 334 * @version 1.0 335 */ 336 class AddBuddyThread implements Runnable 337 { 338 private String errorMessage; 339 private String groupName; 340 private String buddyAlias; 341 private String buddyId; 342 private AddBuddyDialog dialog; 343 private WaitDialog wait; 344 345 /** 346 * Default constructor 347 * @param wait the wait dialog 348 * @param groupName the group to use 349 * @param buddyAlias the buddy's alias 350 * @param buddyId the buddy's JID 351 * @param dialog the AddBuddyDialog that called this thread 352 */ 353 public AddBuddyThread( WaitDialog wait, String groupName, String buddyAlias, String buddyId, AddBuddyDialog dialog ) 354 { 355 this.wait = wait; 356 this.groupName = groupName; 357 this.buddyAlias = buddyAlias; 358 this.buddyId = buddyId.trim(); 359 this.dialog = dialog; 360 } 361 362 /** 363 * Called by the enclosing Thread - will attempt to add the buddy to the Roster, 364 * and will display an error if it wasn't successfull 365 */ 366 public void run() 367 { 368 final Roster roster = BuddyList.getInstance().getConnection().getRoster(); 369 final BuddyStatus buddy = BuddyList.getInstance().getBuddyStatus( buddyId ); 370 if( modify ) BuddyList.getInstance().getBuddyListTree().removeBuddy( buddy, buddy.getGroup() ); 371 372 try { 373 374 if( modify ) 375 { 376 RosterEntry entry = buddy.getRosterEntry(); 377 entry.setName( buddyAlias ); 378 Iterator groups = entry.getGroups(); 379 while( groups.hasNext() ) 380 { 381 RosterGroup g = (RosterGroup)groups.next(); 382 g.removeEntry( entry ); 383 } 384 385 if( groupName != null ) 386 { 387 RosterGroup newGroup = null; 388 newGroup = roster.getGroup( groupName ); 389 if( newGroup == null ) newGroup = roster.createGroup( groupName ); 390 newGroup.addEntry( entry ); 391 buddy.setTempGroup( groupName ); 392 } 393 } 394 395 /* if it's a new entry */ 396 else { 397 398 if( groupName == null ) roster.createEntry( buddyId, buddyAlias, null ); 399 else { 400 roster.createEntry( buddyId, buddyAlias, new String[] { groupName } ); 401 buddy.setTempGroup( groupName ); 402 } 403 } 404 } 405 catch( XMPPException e ) 406 { 407 XMPPError error = e.getXMPPError(); 408 errorMessage = e.getMessage(); 409 if( errorMessage == null ) errorMessage = resources.getString( "unknownError" ); 410 } 411 412 SwingUtilities.invokeLater( new Runnable() 413 { 414 public void run() 415 { 416 wait.dispose(); 417 418 if( errorMessage != null ) 419 { 420 Standard.warningMessage( dialog, resources.getString( "addBuddyDialogTitle" ), errorMessage ); 421 dialog.setVisible( true ); 422 } 423 else { 424 buddy.setRemoved( false ); 425 426 NMOptionDialog.createMessageDialog( null, resources.getString( "addBuddyDialogTitle" ), 427 resources.getString( "buddyAdded" ) ); 428 429 BuddyList.getInstance().getBuddyListTree().addBuddy( buddy ); 430 DialogTracker.removeDialog( dialog ); 431 } 432 } 433 434 } ); 435 } 436 } 437 }