Browse Source

Issue 373

Add Speed and Time Remaining
Cancel Button disables itself when transfer completes.

Send/Wait for the correct acks (Acks are total bytes recieved so far, not bytes recieved this time)
Fix fast-dcc support (Treated as turbo, but with acks at the end.)

git-svn-id: http://svn.dmdirc.com/trunk@4045 00569f92-eb28-0410-84fd-f71c24880f
tags/0.6
Shane Mc Cormack 16 years ago
parent
commit
d6d1a19063
2 changed files with 91 additions and 12 deletions
  1. 26
    6
      src/com/dmdirc/addons/dcc/DCCSend.java
  2. 65
    6
      src/com/dmdirc/addons/dcc/DCCSendWindow.java

+ 26
- 6
src/com/dmdirc/addons/dcc/DCCSend.java View File

@@ -271,7 +271,6 @@ public class DCCSend extends DCC {
271 271
 			transferFile = new File(filename);
272 272
 			if (transferType == TransferType.RECEIVE) {
273 273
 				fileOut = new DataOutputStream(new FileOutputStream(transferFile.getAbsolutePath(), (startpos > 0)));
274
-				//System.out.println("Appending: "+(startpos > 0));
275 274
 			}
276 275
 			out = new DataOutputStream(socket.getOutputStream());
277 276
 			in = new DataInputStream(socket.getInputStream());
@@ -327,8 +326,10 @@ public class DCCSend extends DCC {
327 326
 			readSize = readSize + bytesRead;
328 327
 			
329 328
 			if (bytesRead > 0) {
329
+				if (handler != null) { handler.dataTransfered(this, bytesRead); }
330 330
 				fileOut.write(data, 0, bytesRead);
331
-				out.writeInt(bytesRead);
331
+				// Send ack
332
+				out.writeInt(readSize);
332 333
 				out.flush();
333 334
 				if (readSize == size) {
334 335
 					fileOut.close();
@@ -353,7 +354,6 @@ public class DCCSend extends DCC {
353 354
 	 *         called again.
354 355
 	 */
355 356
 	protected boolean handleSend() {
356
-		if (fileIn == null) { return true; }
357 357
 		try {
358 358
 			final byte[] data = new byte[blockSize];
359 359
 			int bytesRead = fileIn.read(data);
@@ -364,15 +364,35 @@ public class DCCSend extends DCC {
364 364
 				out.write(data, 0, bytesRead);
365 365
 				out.flush();
366 366
 				
367
+				// Wait for acknowlegement packet.
367 368
 				if (!turbo) {
368
-					while (bytesRead > 0) {
369
-						bytesRead = bytesRead - in.readInt();
370
-					}
369
+					int bytesRecieved;
370
+					do {
371
+						bytesRecieved = in.readInt();
372
+					} while ((readSize - bytesRecieved) > 0);
371 373
 				}
372 374
 				
373 375
 				if (readSize == size) {
374 376
 					fileIn.close();
375 377
 					fileIn = null;
378
+					
379
+					// Process all the ack packets that may have been sent.
380
+					// In true turbo dcc mode, none will have been sent and the socket
381
+					// will just close, in fast-dcc mode all the acks will be here,
382
+					// So keep reading acks untill the socket closes (IOException) or we
383
+					// have recieved all the acks.
384
+					if (turbo) {
385
+						int ack = 0;
386
+						do {
387
+							try {
388
+								ack = in.readInt();
389
+							} catch (IOException e) {
390
+								break;
391
+							}
392
+						} while (ack > 0 && (readSize - ack) > 0);
393
+					}
394
+					
395
+					return false;
376 396
 				}
377 397
 				
378 398
 				return true;

+ 65
- 6
src/com/dmdirc/addons/dcc/DCCSendWindow.java View File

@@ -54,12 +54,27 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
54 54
 	/** Total data transfered */
55 55
 	private long transferCount = 0;
56 56
 	
57
+	/** Time Started */
58
+	private long timeStarted = 0;
59
+	
57 60
 	/** Progress Bar */
58 61
 	private final JProgressBar progress = new JProgressBar();
59 62
 	
60 63
 	/** Status Label */
61 64
 	private final JLabel status = new JLabel("Status: Waiting");
62 65
 	
66
+	/** Speed Label */
67
+	private final JLabel speed = new JLabel("Speed: Unknown");
68
+	
69
+	/** Time Label */
70
+	private final JLabel remaining = new JLabel("Time Remaining: Unknown");
71
+	
72
+	/** Time Taken */
73
+	private final JLabel taken = new JLabel("Time Taken: 00:00");
74
+	
75
+	/** Button */
76
+	private final JButton button = new JButton("Cancel");
77
+	
63 78
 	/**
64 79
 	 * Creates a new instance of DCCSendWindow with a given DCCSend object.
65 80
 	 *
@@ -78,8 +93,6 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
78 93
 		
79 94
 		getContentPane().setLayout(new MigLayout());
80 95
 		
81
-		transferCount = dcc.getFileStart();
82
-		
83 96
 		progress.setMinimum(0);
84 97
 		progress.setMaximum(100);
85 98
 		progress.setStringPainted(true);
@@ -93,11 +106,12 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
93 106
 			getContentPane().add(new JLabel("From: "+targetNick), "wrap");
94 107
 		}
95 108
 		getContentPane().add(status, "wrap");
109
+		getContentPane().add(speed, "wrap");
110
+		getContentPane().add(remaining, "wrap");
111
+		getContentPane().add(taken, "wrap");
96 112
 		getContentPane().add(progress, "growx, wrap");
97 113
 		
98
-		final JButton button = new JButton("Cancel");
99 114
 		button.addActionListener(this);
100
-		
101 115
 		getContentPane().add(button, "wrap, align right");
102 116
 		
103 117
 		plugin.addWindow(this);
@@ -106,7 +120,7 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
106 120
 	/** {@inheritDoc} */
107 121
 	public void actionPerformed(final ActionEvent e) {
108 122
 		if (e.getActionCommand().equals("Cancel")) {
109
-			((JButton)e.getSource()).setEnabled(false);
123
+			button.setEnabled(false);
110 124
 			dcc.close();
111 125
 		}
112 126
 	}
@@ -119,7 +133,7 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
119 133
 	 */
120 134
 	public void dataTransfered(final DCCSend dcc, final int bytes) {
121 135
 		transferCount += bytes;
122
-		final double percent = (100.00 / dcc.getFileSize()) * transferCount;
136
+		final double percent = (100.00 / dcc.getFileSize()) * (transferCount + dcc.getFileStart());
123 137
 		
124 138
 		if (dcc.getType() == DCCSend.TransferType.SEND) {
125 139
 			status.setText("Status: Sending");
@@ -127,9 +141,51 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
127 141
 			status.setText("Status: Recieving");
128 142
 		}
129 143
 		
144
+		updateSpeedAndTime();
145
+		
130 146
 		progress.setValue((int)Math.floor(percent));
131 147
 	}
132 148
 	
149
+	/**
150
+	 * Update the transfer speed, time remaining and time taken labels.
151
+	 */
152
+	public void updateSpeedAndTime() {
153
+		final long time = (System.currentTimeMillis() - timeStarted) / 1000;
154
+		final double bytesPerSecond = (time > 0) ? (transferCount / time) : 0;
155
+		
156
+		if (bytesPerSecond > 1048576) {
157
+			speed.setText(String.format("Speed: %.2f MB/s", (bytesPerSecond/1048576)));
158
+		} else if (bytesPerSecond > 1024) {
159
+			speed.setText(String.format("Speed: %.2f KB/s", (bytesPerSecond/1024)));
160
+		} else {
161
+			speed.setText(String.format("Speed: %f B/s", bytesPerSecond));
162
+		}
163
+		
164
+		final long remaningBytes = dcc.getFileSize() - dcc.getFileStart() - transferCount;
165
+		final double remainingSeconds = (bytesPerSecond > 0) ? (remaningBytes / bytesPerSecond) : 1;
166
+		
167
+		remaining.setText(String.format("Time Remaining: %s", duration((int)Math.floor(remainingSeconds))));
168
+		taken.setText(String.format("Time Taken: %s", duration(time)));
169
+	}
170
+	
171
+	/**
172
+	 * Get the duration in seconds as a string.
173
+	 *
174
+	 * @param secondsInput to get duration for
175
+	 * @return Duration as a string
176
+	 */
177
+	private String duration(final long secondsInput) {
178
+		final StringBuilder result = new StringBuilder();
179
+		final long hours = (secondsInput / 3600);
180
+		final long minutes = (secondsInput / 60 % 60);
181
+		final long seconds = (secondsInput % 60);
182
+		
183
+		if (hours > 0) { result.append(hours+":"); }
184
+		result.append(String.format("%0,2d:%0,2d",minutes,seconds));
185
+		
186
+		return result.toString();
187
+	}
188
+	
133 189
 	/**
134 190
 	 * Called when the socket is closed
135 191
 	 *
@@ -137,11 +193,13 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
137 193
 	 */
138 194
 	@Override
139 195
 	public void socketClosed(final DCCSend dcc) {
196
+		button.setEnabled(false);
140 197
 		if (transferCount == dcc.getFileSize()) {
141 198
 			status.setText("Status: Transfer Compelete.");
142 199
 		} else {
143 200
 			status.setText("Status: Transfer Failed.");
144 201
 		}
202
+		updateSpeedAndTime();
145 203
 	}
146 204
 	
147 205
 	/**
@@ -152,6 +210,7 @@ public class DCCSendWindow extends DCCFrame implements DCCSendInterface, ActionL
152 210
 	@Override
153 211
 	public void socketOpened(final DCCSend dcc) {
154 212
 		status.setText("Status: Socket Opened");
213
+		timeStarted = System.currentTimeMillis();
155 214
 	}
156 215
 	
157 216
 	/**

Loading…
Cancel
Save