Source code: jpl2/link/gui/FileDownload.java
1
2 /***********************************************************************
3 * JavaPsionLink 1.0, a java implementation of the psion link protocol
4 * Copyright (C) 2001-2003 John S Montgomery (john.montgomery@lineone.net)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ************************************************************************/
20 package jpl2.link.gui;
21
22 import jpl2.link.*;
23 import jpl2.common.gui.*;
24
25 import java.awt.*;
26 import java.awt.event.*;
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31
32
33
34 /** Dialog to show when downloading/uploading a file(s). **/
35
36 public class FileDownload {
37 private Dialog dialog = null;
38 private Component currentFile = null;
39 private Component size = null;
40 private Component speed = null;
41 private Component numFiles = null;
42 private Component progress = null;
43 private Thread downloadThread = null;
44 private Image image = null;
45 private Icon icon = null;
46 private Frame frame = null;
47 private boolean yesToAll = false;
48 private boolean cancelled = false;
49 private JPLToolkit tk = JPLToolkit.getToolkit();
50
51 public FileDownload( Frame frame, String title ) {
52 dialog = tk.makeDialog( frame, title, false );
53 this.frame = frame;
54 progress = tk.makeProgressBar();
55 currentFile = tk.makeLabel( "@res:calculateFiles" );
56 size = tk.makeLabel( "" );
57 speed = tk.makeLabel( "" );
58 numFiles = tk.makeLabel( "" );
59 Container iconPanel = tk.makePanel();
60 icon = new Icon();
61 iconPanel.add( icon );
62 tk.add( dialog, iconPanel, BorderLayout.WEST );
63
64 Container labels = tk.makePanel();
65 labels.setLayout( new GridLayout( 4, 1 ) );
66 labels.add( currentFile );
67 labels.add( size );
68 labels.add( speed );
69 labels.add( numFiles );
70 tk.add( dialog, labels, BorderLayout.CENTER );
71
72 tk.add( dialog, new Icon(), BorderLayout.EAST );
73
74 Component stopButton = tk.makeButton( "@res:stopButton", "stop", new ActionListener() {
75 public void actionPerformed( ActionEvent ae ) {
76 cancel();
77 }
78 } );
79
80 Container controlsPanel = tk.makePanel();
81 controlsPanel.setLayout( new GridLayout( 2, 1 ) );
82 Container buttonPanel = tk.makePanel();
83 buttonPanel.add( stopButton );
84 Container progressPanel = tk.makePanel();
85 progressPanel.add( progress );
86 controlsPanel.add( progressPanel );
87 controlsPanel.add( buttonPanel );
88 tk.add( dialog, controlsPanel, BorderLayout.SOUTH );
89 tk.setCancelButton( dialog, stopButton );
90 //downloadThread = Thread.currentThread();
91 dialog.pack();
92 tk.centreWindow( frame, dialog );
93 }
94
95 public FileDownload( Frame frame, boolean downloading ) {
96 this( frame, downloading ? "@res:downloading" : "@res:uploading" );
97 }
98
99 public void setTitle( String title ) {
100 // TODO make sure dialog expands to show title properly
101 dialog.setTitle( JPLToolkit.getResourceString( title ) );
102 dialog.invalidate();
103 //dialog.validate();
104 //dialog.doLayout();
105 dialog.pack();
106 }
107
108 public void reset() {
109 tk.setText( currentFile, "@res:calculateFiles" );
110 tk.setText( size, "" );
111 tk.setText( speed, "" );
112 tk.setText( numFiles, "" );
113 image = null;
114 icon.repaint();
115 }
116
117 public void setProgressMax( int max ) {
118 tk.setProgressBarMax( progress, max );
119 }
120
121 public void setProgressValue( int value ) {
122 tk.setProgressBarValue( progress, value );
123 }
124
125 private int approxSpeed = 0;
126
127 public void setSpeed( double ks ) {
128 int nspeed = (int)(10*ks);
129 if ( nspeed == approxSpeed )
130 return;
131 approxSpeed = nspeed;
132
133 // ##.# K/s
134 tk.setText( speed, "@res:ks", new Object[] { new Double( ks ) } );
135 speed.repaint();
136 }
137
138 public void setNumFiles( int num ) {
139 // num files
140 tk.setText( numFiles, "@res:filesRemaining", new Object[] { new Integer( num ) } );
141 numFiles.repaint();
142 }
143
144 public void setCurrentFile( PsionFile file ) {
145 tk.setText( currentFile, file.getName() );
146
147 if ( !file.isDirectory() ) {
148 tk.setText( size, "@res:fileSize", new Object[] { new Integer( file.getSize() ) } );
149 }
150 else {
151 tk.setText( size, "" );
152 }
153
154 image = Images.getIconImage( file );
155
156 if ( file.isDirectory() ) {
157 progress.setVisible( false );
158 }
159 else {
160 progress.setVisible( true );
161 }
162
163 //dialog.invalidate();
164
165 //pack();
166 dialog.repaint();
167 icon.repaint();
168 //currentFile.repaint();
169 }
170
171 /** Check whether the file already exists and will be written over.
172 * Ask the user whether they want to overwrite the file.
173 **/
174 public void checkOverwrite( PsionFile file ) {
175 try {
176 if ( !yesToAll && file.exists() ) {
177 // show a dialog here
178 showOverwriteDialog( file.getParent(), file.getName() );
179 }
180 }
181 catch( Exception e ) {
182 e.printStackTrace();
183 }
184 }
185
186 public void checkOverwrite( File file ) {
187
188 if ( !yesToAll && file.exists() ) {
189 // show a dialog here
190 String path = file.getParent();
191 showOverwriteDialog( path, file.getName() );
192 }
193
194 }
195
196 private Dialog overWriteDialog = null;
197
198 public void showOverwriteDialog( String path, String fileName ) {
199 String msg = JPLToolkit.getResourceString( "@res:replaceFileMsg", new Object[] { fileName, path } );
200 String title = JPLToolkit.getResourceString( "@res:replaceFile", new Object[] { fileName } );
201 String result = tk.doMultipleQueryDialog( frame, title, msg );
202 if ( result.equals( "yes all" ) )
203 yesToAll = true;
204 else if ( result.equals( "no" ) )
205 cancel();
206 }
207
208 public void setCurrentFile( File file ) {
209
210 tk.setText( currentFile, file.getName() );
211
212 if ( !file.isDirectory() ) {
213 tk.setText( size, "@res:fileSize", new Object[] { new Long( file.length() ) } );
214 }
215 else {
216 tk.setText( size, "" );
217 }
218
219 image = Images.getImage( file.isDirectory() ? "folder.gif" : "generic.gif" );
220
221 if ( file.isDirectory() ) {
222 progress.setVisible( false );
223 }
224 else {
225 progress.setVisible( true );
226 }
227
228 //dialog.invalidate();
229 //
230
231 dialog.repaint();
232 icon.repaint();
233 }
234
235 public void setCurrentFile( String fileName, long fileSize ) {
236 tk.setText( currentFile, fileName );
237
238 tk.setText( size, "@res:fileSize", new Object[] { new Long( fileSize ) } );
239
240 image = Images.getImage( "generic.gif" );
241
242 progress.setVisible( true );
243
244 dialog.repaint();
245 icon.repaint();
246 }
247
248 public void show() {
249 dialog.show();
250 }
251
252 private final byte[] buffer = new byte[ 2048 ];
253
254 /** Trannsfer length bytes from in to out, updating progress bar and speed
255 * on dialog as we go.
256 **/
257 public void transfer( int length, InputStream in, OutputStream out ) throws IOException {
258
259 setProgressMax( length );
260 long start = System.currentTimeMillis();
261
262 int remaining = length;
263 while( remaining > 0 ) {
264 if ( isCancelled() )
265 break;
266
267 synchronized( buffer ) {
268 int read = in.read( buffer );
269 //System.out.println( "read " + read );
270 remaining -= read;
271 out.write( buffer, 0, read );
272 int uploaded = (int)(length-remaining);
273 setProgressValue( uploaded );
274 long end = System.currentTimeMillis();
275 long duration = end-start;
276 setSpeed( (1000.0*uploaded/1024.0)/duration );
277 }
278 }
279
280 out.flush();
281 }
282
283 public synchronized void cancel() {
284 cancelled = true;
285 //downloadThread.interrupt();
286 dialog.setVisible( false );
287 }
288
289 public synchronized boolean isCancelled() {
290 return cancelled;
291 }
292
293 class Icon extends Component {
294
295 public Dimension getPreferredSize() {
296 return new Dimension( 28, 28 );
297 }
298
299 public void paint( Graphics g ) {
300 if ( image == null || icon != this )
301 return;
302 g.setColor( Color.white );
303 g.fillRect( 0, 0, getSize().width-1, getSize().height-1 );
304 g.setColor( Color.black );
305 g.drawRect( 0, 0, getSize().width-1, getSize().height-1 );
306 g.drawImage( image, 2, 2, this );
307 }
308
309 }
310
311 }