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 }