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.Component; 022 import java.awt.Dimension; 023 import java.awt.event.ActionEvent; 024 import java.awt.event.ActionListener; 025 import java.awt.event.MouseAdapter; 026 import java.awt.event.MouseEvent; 027 import java.io.BufferedReader; 028 import java.io.File; 029 import java.io.FileFilter; 030 import java.io.FileNotFoundException; 031 import java.io.FileReader; 032 import java.io.IOException; 033 import java.text.SimpleDateFormat; 034 import java.util.*; 035 036 import javax.swing.BorderFactory; 037 import javax.swing.Box; 038 import javax.swing.BoxLayout; 039 import javax.swing.ImageIcon; 040 import javax.swing.JButton; 041 import javax.swing.JFrame; 042 import javax.swing.JLabel; 043 import javax.swing.JList; 044 import javax.swing.JOptionPane; 045 import javax.swing.JPanel; 046 import javax.swing.JScrollPane; 047 import javax.swing.JSplitPane; 048 import javax.swing.ListCellRenderer; 049 import javax.swing.ListSelectionModel; 050 import javax.swing.WindowConstants; 051 052 import com.valhalla.gui.*; 053 import com.valhalla.jbother.*; 054 import com.valhalla.settings.Settings; 055 056 /** 057 * Allows the user to view the log of any contact 058 * Displays a dialog that allows you to view the log of any Jabber 059 * user you have contacted. You can view the log by date and time 060 * 061 * @author Adam Olsen 062 * @version 1.0 063 */ 064 public class LogViewerDialog extends JFrame 065 { 066 private ResourceBundle resources = ResourceBundle.getBundle( "JBotherBundle", Locale.getDefault() ); 067 private String logDirectory; 068 private JList logList; 069 private JPanel container = new JPanel(); 070 private JPanel rightPanel = new JPanel(); 071 private ConversationArea logView; 072 private File logDirectoryFile; 073 private JButton closeButton = new JButton( resources.getString( "closeButton" ) ), 074 clearButton = new JButton( resources.getString( "clearButton" ) ); 075 076 private JSplitPane splitPane; 077 private File fileList[]; 078 private LogViewerCaller caller; 079 private LogViewerDialog thisPointer = this; 080 081 /** 082 * Default constructor 083 * Can be passed a ChatRoomPanel, HeadlineWindow, and a ChatPanel as the caller 084 * @param caller the object that called this dialog 085 * @param entryName the user who's log is to be viewed 086 */ 087 public LogViewerDialog( LogViewerCaller caller, String entryName ) 088 { 089 super( "Log Viewer (" + entryName + ")" ); 090 setTitle( resources.getString( "logViewer" ) + " (" + entryName + ")" ); 091 092 ImageIcon icon = StatusIconCache.getStatusIcon(org.jivesoftware.smack.packet.Presence.Mode.AVAILABLE); 093 if ( icon != null ) setIconImage( icon.getImage() ); 094 095 if( caller != null ) this.caller = caller; 096 097 logDirectory = JBother.profileDir + File.separatorChar + "logs" + File.separatorChar + 098 entryName.replaceAll( "@", "_at_" ).replaceAll( "\\/", "-" ); 099 100 logDirectoryFile = new File( logDirectory ); 101 102 container.setLayout( new BoxLayout( container, BoxLayout.X_AXIS ) ); 103 setContentPane( container ); 104 105 logView = new ConversationArea(); 106 107 logView.setPreferredSize( new Dimension( 500, 350 ) ); 108 109 rightPanel.setLayout( new BoxLayout( rightPanel, BoxLayout.Y_AXIS ) ); 110 rightPanel.add( new JScrollPane( logView ) ); 111 112 JPanel buttonPanel = new JPanel(); 113 buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.X_AXIS ) ); 114 buttonPanel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 0, 0 ) ); 115 buttonPanel.add( Box.createHorizontalGlue() ); 116 buttonPanel.add( clearButton ); 117 buttonPanel.add( closeButton ); 118 rightPanel.add( buttonPanel ); 119 120 splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, new JScrollPane( loadLogFiles() ), rightPanel ); 121 splitPane.setDividerLocation( 150 ); 122 splitPane.setOneTouchExpandable( true ); 123 124 container.add( splitPane ); 125 container.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); 126 127 setUpListeners(); 128 129 pack(); 130 Standard.cascadePlacement( this ); 131 DialogTracker.addDialog( this, false, true ); 132 133 if( logList.getModel().getSize() >= 1 ) setVisible( true ); 134 else { 135 Standard.warningMessage( null, resources.getString( "logViewer" ), 136 resources.getString( "noLogData" ) ); 137 DialogTracker.removeDialog( this ); 138 } 139 } 140 141 /** 142 * Returns a formatted date string that is used in many places in JBother 143 * @return the formatted date and time 144 */ 145 public static String getDateName() 146 { 147 SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd-HH-mm-ss" ); 148 String date = formatter.format( new Date() ); 149 return date; 150 } 151 152 /** 153 * Sets up the listeners for the various events 154 */ 155 private void setUpListeners() 156 { 157 setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); 158 159 closeButton.addActionListener( new ActionListener() 160 { 161 public void actionPerformed( ActionEvent e ) 162 { 163 DialogTracker.removeDialog( thisPointer ); 164 } 165 } ); 166 167 clearButton.addActionListener( new ActionListener() 168 { 169 public void actionPerformed( ActionEvent e ) 170 { 171 clearHandler(); 172 } 173 } ); 174 175 logList.addMouseListener( new LogListMouseListener() ); 176 } 177 178 /** 179 * Listens for someone to click on an entry date 180 * and populates the textArea with the log data 181 * @author Adam Olsen 182 * @version 1.0 183 */ 184 private class LogListMouseListener extends MouseAdapter 185 { 186 public void mouseClicked( MouseEvent e ) 187 { 188 File file = (File)logList.getSelectedValue(); 189 String fileText = ""; 190 191 try { 192 // open the selected log 193 FileReader fr = new FileReader( file ); 194 BufferedReader in = new BufferedReader( fr ); 195 String line; 196 while( ( line = in.readLine() ) != null ) fileText += line; 197 fr.close(); 198 } 199 catch( FileNotFoundException fnfe ) { } 200 catch( IOException ioe ) { } 201 202 logView.setText( fileText ); 203 } 204 } 205 206 /** 207 * Clears all log data (deletes all log entries) 208 */ 209 private void clearHandler() 210 { 211 int result = JOptionPane.showConfirmDialog( null, 212 resources.getString( "sureClearLog" ), resources.getString( "clearLogs" ), JOptionPane.YES_NO_OPTION ); 213 214 if( result == 0 ) 215 { 216 if( caller != null ) 217 { 218 caller.closeLog(); 219 caller.startLog(); 220 } 221 222 for( int i = 0; i < fileList.length; i++ ) fileList[i].delete(); 223 DialogTracker.removeDialog( this ); 224 } 225 } 226 227 /** 228 * Returns a list of all available log entries 229 * @return the list of log entries 230 */ 231 private JList loadLogFiles() 232 { 233 logList = new JList(); 234 logList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); 235 logList.setCellRenderer( new LogListRenderer() ); 236 237 if( !logDirectoryFile.isDirectory() ) return logList; 238 239 // opens the directory and lists the files 240 fileList = logDirectoryFile.listFiles( new LogFileFilter() ); 241 if( fileList.length == 0 ) return logList; 242 243 String fileText = ""; 244 245 Arrays.sort( fileList, Collections.reverseOrder() ); 246 247 // displays the most recent entry 248 try { 249 FileReader fr = new FileReader( fileList[0] ); 250 BufferedReader in = new BufferedReader( fr ); 251 String line; 252 while( ( line = in.readLine() ) != null ) fileText += line; 253 fr.close(); 254 } 255 catch( FileNotFoundException fnfe ) { return new JList(); } 256 catch( IOException ioe ) { return new JList(); } 257 258 logView.setText( fileText ); 259 260 logList.setListData( fileList ); 261 logList.setSelectedIndex( 0 ); 262 return logList; 263 } 264 } 265 266 /** 267 * Displays each log entry as a date and time 268 * @author Adam Olsen 269 * @version 1.0 270 */ 271 class LogListRenderer extends JLabel implements ListCellRenderer 272 { 273 /** 274 * Sets the background to opaque 275 */ 276 public LogListRenderer() 277 { 278 setOpaque( true ); 279 } 280 281 /** 282 * Renders each entry 283 */ 284 public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus ) 285 { 286 File file = (File)value; 287 288 String dateString[] = file.toString().replaceAll( ".*\\" + File.separatorChar , 289 "" ).replaceAll( "\\.log\\.html", "" ).split( "\\-" ); 290 291 try { 292 setText( dateString[1] + "-" + dateString[2] + "-" + dateString[0] + " " + dateString[3] + ":" + dateString[4] + ":" + dateString[5] ); 293 } 294 catch( Exception e ) 295 { 296 setText( "Invalid Date" ); 297 } 298 299 setBackground( isSelected ? list.getSelectionBackground() : list.getBackground() ); 300 setForeground( isSelected ? list.getSelectionForeground() : list.getForeground() ); 301 list.validate(); 302 303 return this; 304 } 305 } 306 307 /** 308 * A filter to only accept html files 309 * @author Adam Olsen 310 * @version 1.0 311 */ 312 class LogFileFilter implements FileFilter 313 { 314 // accept html files 315 public boolean accept( File f ) 316 { 317 if( f.isDirectory() ) return false; 318 319 if( f.length() <= 0.0 ) return false; 320 321 String extension = Utils.getExtension( f ); 322 323 if( extension != null ) 324 { 325 if( extension.equals( Utils.html ) ) 326 { 327 return true; 328 } 329 else { 330 return false; 331 } 332 } 333 334 return false; 335 } 336 }