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.groupchat;
020    
021    import java.awt.*;
022    import java.awt.event.*;
023    import java.io.*;
024    import java.util.*;
025    import javax.swing.*;
026    import com.valhalla.gui.*;
027    import com.valhalla.jbother.*;
028    import com.valhalla.settings.Settings;
029    
030    /**
031     * Allows the user to create bookmarks for each of their favorite group chat rooms
032     *
033     * @author Adam Olsen
034     * @version 1.0
035    */
036    public class GroupChatBookmarks extends JDialog
037    {
038            private ResourceBundle resources = ResourceBundle.getBundle( "JBotherBundle", Locale.getDefault() );
039            private JPanel container = new JPanel();
040            private JList bookMarkList;
041            private JPanel rightPanel = new JPanel();
042            private JPanel leftPanel = new JPanel();
043            private JPanel buttonPanel = new JPanel();
044            private JPanel inputPanel = new JPanel();
045            private JButton                 saveButton = new JButton( resources.getString( "saveButton" ) ),
046                                                            openButton = new JButton( resources.getString( "openButton" ) ),
047                                                            cancelButton = new JButton( resources.getString( "cancelButton" ) );
048            private File bookMarksDirectory;
049            private JTextField              roomBox = new JTextField( 15 ),
050                                                            serverBox = new JTextField( 20 ),
051                                                            nickBox = new JTextField( 15 );
052            private int row = 0;
053            private GridBagLayout grid = new GridBagLayout();
054            private GridBagConstraints c = new GridBagConstraints();
055            private File fileList[];
056            private JPopupMenu deleteMenu = new JPopupMenu();
057            private JMenuItem deleteItem = new JMenuItem( resources.getString( "deleteButton" ) );
058            private String lastOpenedBookmark;
059    
060            /**
061             * Sets up the visual components of the bookmark dialog
062            */
063            public GroupChatBookmarks()
064            {
065                    super( BuddyList.getInstance(), "Group Chat Bookmarks" );
066                    setTitle( resources.getString( "groupChatBookmarksDialogTitle" ) );
067    
068                    container.setLayout( new BoxLayout( container, BoxLayout.X_AXIS ) );
069                    container.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
070    
071                    bookMarkList = new JList();
072                    bookMarkList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
073                    bookMarkList.setCellRenderer( new ListRenderer() );
074    
075    
076                    leftPanel.setBackground( Color.WHITE );
077                    leftPanel.setLayout( new GridLayout( 0, 1 ) );
078                    setContentPane( container );
079    
080                    deleteMenu.add( deleteItem );
081    
082                    bookMarksDirectory = new File( JBother.profileDir + File.separatorChar + "gcbookmarks" );
083    
084                    loadBookmarks();
085                    leftPanel.add( new JScrollPane( bookMarkList ) );
086                    leftPanel.setPreferredSize( new Dimension( 120, 200 ) );
087    
088                    inputPanel.setBorder( BorderFactory.createTitledBorder( resources.getString( "groupChatBookmarksDialogTitle" ) ) );
089                    rightPanel.setLayout( new BoxLayout( rightPanel, BoxLayout.Y_AXIS ) );
090    
091                    inputPanel.setLayout( grid );
092                    c.anchor = GridBagConstraints.WEST;
093    
094                    createInputBox( resources.getString( "room" ) + ":", roomBox );
095                    createInputBox( resources.getString( "server" ) + ":", serverBox );
096                    createInputBox( resources.getString( "nickname" ) + ":", nickBox );
097    
098                    container.add( leftPanel );
099                    container.add( Box.createRigidArea( new Dimension( 5, 0 ) ) );
100    
101                    //this is the space taker
102                    JLabel blankLabel = new JLabel( "" );
103                    c.weighty = 1;
104                    c.weightx = 1;
105                    c.gridx = 0;
106                    c.gridwidth = 3;
107                    c.gridy++;
108                    grid.setConstraints( blankLabel, c );
109                    inputPanel.add( blankLabel );
110                    buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.X_AXIS ) );
111                    buttonPanel.add( Box.createHorizontalGlue() );
112                    buttonPanel.add( saveButton );
113                    buttonPanel.add( openButton );
114                    buttonPanel.add( cancelButton );
115    
116    
117                    rightPanel.add( inputPanel );
118                    rightPanel.add( buttonPanel );
119                    container.add( rightPanel );
120    
121                    setListeners();
122    
123                    setSize( 400, 200 );
124                    pack();
125                    setLocationRelativeTo( null );
126                    DialogTracker.addDialog( this, true, true );
127            }
128    
129            /**
130             * Adds event listeners to components in the bookmark window
131            */
132            private void setListeners()
133            {
134                    setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
135                    cancelButton.addActionListener( new ActionListener()
136                    {
137                            public void actionPerformed( ActionEvent e ) { dispose(); }
138                    } );
139    
140                    saveButton.addActionListener( new ActionListener()
141                    {
142                            public void actionPerformed( ActionEvent e ) { saveBookmark(); }
143                    } );
144    
145                    openButton.addActionListener( new ActionListener()
146                    {
147                            public void actionPerformed( ActionEvent e ) { openHandler(); }
148                    } );
149    
150                    bookMarkList.addMouseListener( new RightClickListener() );
151                    deleteItem.addActionListener( new DeleteListener() );
152            }
153    
154            /**
155             * Writes a bookmark to the bookmarks file on disk
156            */
157            private void saveBookmark()
158            {
159                    if( !checkData() ) return;
160    
161                    if( !bookMarksDirectory.isDirectory() && !bookMarksDirectory.mkdir() )
162                    {
163                            com.valhalla.Logger.debug( "Could not create bookmarks directory." );
164                            return;
165                    }
166    
167                    String defaultString = lastOpenedBookmark;
168                    if( lastOpenedBookmark == null || lastOpenedBookmark.equals( "" ) ) defaultString = roomBox.getText();
169    
170                    String result = (String)JOptionPane.showInputDialog( null,
171                            resources.getString( "enterBookmarkName" ),
172                            resources.getString( "saveBookmark" ), JOptionPane.QUESTION_MESSAGE, null, null, defaultString );
173    
174                    if( result == null || result.equals( "" ) ) return;
175    
176                    try {
177                            FileWriter fw = new FileWriter( new File( bookMarksDirectory, result + ".gcb" ) );
178                            PrintWriter out = new PrintWriter( fw );
179    
180                            out.println( roomBox.getText() );
181                            out.println( serverBox.getText() );
182                            out.println( nickBox.getText() );
183    
184                            fw.close();
185                    }
186                    catch( IOException e ) { Standard.warningMessage( this, resources.getString( "saveBookmark" ),
187                            resources.getString( "unkownError" ) ); }
188    
189                    loadBookmarks();
190            }
191    
192            /**
193             * Makes sure all of the required information to save a bookmark is filled in
194             * @return true if the information is completely filled out
195            */
196            private boolean checkData()
197            {
198                    if( roomBox.getText().equals( "" ) ||
199                            serverBox.getText().equals( "" ) || nickBox.getText().equals( "" ) )
200                    {
201                            Standard.warningMessage( this, resources.getString( "enterAllFields" ),
202                                    resources.getString( "groupChatBookmarksDialogTitle" ) );
203                            return false;
204                    }
205    
206                    return true;
207            }
208    
209            /**
210             * Deletes a bookmark from disk
211             * @author Adam Olsen
212             * @version 1.0
213            */
214            class DeleteListener implements ActionListener
215            {
216                    public void actionPerformed( ActionEvent e )
217                    {
218                            int result = JOptionPane.showConfirmDialog( null,
219                                    resources.getString( "sureDelete" ), resources.getString( "deleteBookmark" ), JOptionPane.YES_NO_OPTION );
220    
221                            if( result != 0 ) return;
222    
223                            ListModel model = bookMarkList.getModel();
224                            File file = (File)model.getElementAt( bookMarkList.getSelectedIndex() );
225                            file.delete();
226                            loadBookmarks();
227                            validate();
228                    }
229            }
230    
231            /**
232             * Shows a menu on the bookmark items allowing you to delete one of them
233             * @author Adam Olsen
234             * @version 1.0
235            */
236            class RightClickListener extends MouseAdapter
237            {
238                    public void mousePressed( MouseEvent e ) { checkPop( e ); }
239                    public void mouseReleased( MouseEvent e ) { checkPop( e ); }
240                    public void mouseClicked( MouseEvent e ) { checkPop( e ); }
241    
242                    public void checkPop( MouseEvent e )
243                    {
244                            if( e.isPopupTrigger() )
245                            {
246                                    int index = bookMarkList.locationToIndex( new Point( e.getX(), e.getY() ) );
247                                    bookMarkList.setSelectedIndex( index );
248                                    deleteMenu.show( e.getComponent(), e.getX(), e.getY() );
249                            }
250                            else {
251                                    loadBookmark();
252                                    if( e.getClickCount() >= 2 ) openHandler();
253                            }
254                    }
255            }
256    
257            /**
258             * Opens a bookmark and fills out the fields with it's information
259            */
260            private void loadBookmark()
261            {
262                    ListModel model = bookMarkList.getModel();
263                    File file = (File)model.getElementAt( bookMarkList.getSelectedIndex() );
264    
265                    try {
266                            FileReader fr = new FileReader( file );
267                            BufferedReader in = new BufferedReader( fr );
268    
269                            String line = in.readLine();
270                            if( line != null ) roomBox.setText( line );
271                            line = in.readLine();
272                            if( line != null ) serverBox.setText( line );
273                            line = in.readLine();
274                            if( line != null ) nickBox.setText( line );
275    
276                            fr.close();
277                    }
278                    catch( IOException e )
279                    {
280                            Standard.warningMessage( this, resources.getString( "openBookmark" ),
281                                    resources.getString( "unkownError" ) );
282                            return;
283                    }
284    
285                    lastOpenedBookmark = file.getName().replaceAll( "\\.gcb", "" ).replaceAll( ".*\\" + File.separatorChar, "" );
286            }
287    
288            /**
289             * Opens a connection to a groupchat room
290            */
291            private void openHandler()
292            {
293                    checkData();
294    
295                    if( BuddyList.getInstance().getTabFrame() != null &&
296                            BuddyList.getInstance().getTabFrame().isRoomOpen( roomBox.getText() + "@" + serverBox.getText() ) )
297                    {
298                            Standard.warningMessage( this, resources.getString( "openBookmark" ), resources.getString( "alreadyInRoom" ) );
299                            return;
300                    }
301    
302                    ChatRoomPanel window = new ChatRoomPanel( roomBox.getText() + "@" + serverBox.getText(), nickBox.getText() );
303                    window.startChat();
304                    dispose();
305            }
306    
307            /**
308             * Loads all the bookmarks and puts them in the list of bookmarks
309            */
310            private void loadBookmarks()
311            {
312                    if( !bookMarksDirectory.isDirectory() )
313                    {
314                            bookMarkList.setListData( new String[] { } );
315                            return;
316                    }
317    
318                    fileList = bookMarksDirectory.listFiles( new GCFileFilter() );
319                    if( fileList.length == 0 )
320                    {
321                            bookMarkList.setListData( new String[] { } );
322                            return;
323                    }
324    
325                    Arrays.sort( fileList );
326    
327                    bookMarkList.setListData( fileList );
328            }
329    
330            /**
331             * Creates a JTextField with a label
332             * @param label the name of the the label
333             * @param box the JTextField
334            */
335            private void createInputBox( String label, Container box )
336            {
337                    JLabel labelBox = new JLabel( label + "    " );
338    
339                    c.gridy = row++;
340                    c.gridx = 0;
341                    grid.setConstraints( labelBox, c );
342                    inputPanel.add( labelBox );
343    
344                    c.gridx = 1;
345                    grid.setConstraints( box, c );
346                    inputPanel.add( box );
347            }
348    }
349    
350    /**
351     * Displays the different group chat bookmarks
352     * @author Adam Olsen
353     * @version 1.0
354    */
355    class ListRenderer extends JLabel implements ListCellRenderer
356    {
357            public ListRenderer()
358            {
359                    setOpaque( true );
360            }
361    
362            public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus )
363            {
364                    File file = (File)value;
365    
366                    setText( file.toString().replaceAll( "\\.gcb", "" ).replaceAll( ".*\\" + File.separatorChar, "" ) );
367    
368                    setBackground( isSelected ? list.getSelectionBackground() : list.getBackground() );
369                    setForeground( isSelected ? list.getSelectionForeground() : list.getForeground() );
370                    list.validate();
371    
372                    return this;
373            }
374    }
375    
376    /**
377     * Filters out everything but .gcb extensions
378     * @author Adam Olsen
379     * @version 1.0
380    */
381    class GCFileFilter implements FileFilter
382    {
383            /**
384             * @return true if the file is a directory or a .gcb file
385            */
386            public boolean accept( File f )
387            {
388                    if( f.isDirectory() ) return false;
389    
390                    String extension = Utils.getExtension( f );
391    
392                    if( extension != null )
393                    {
394                            if( extension.equals( Utils.gcb ) )
395                            {
396                                            return true;
397                            }
398                            else {
399                                    return false;
400                            }
401                    }
402    
403                    return false;
404            }
405    }