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    }