source: trunk/gli/src/org/greenstone/gatherer/gui/DownloadPane.java@ 10396

Last change on this file since 10396 was 10342, checked in by mdewsnip, 19 years ago

Tidied up a lot of path variables. These were all over the place, and were often duplicated. Now all GLI related paths are accessed via static methods in the Gatherer class.

  • Property svn:keywords set to Author Date Id Revision
File size: 13.4 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.File;
42import java.net.*;
43import java.util.*;
44import javax.swing.*;
45import javax.swing.border.*;
46import javax.swing.event.*;
47import javax.swing.tree.*;
48import org.greenstone.gatherer.Configuration;
49import org.greenstone.gatherer.Dictionary;
50import org.greenstone.gatherer.Gatherer;
51import org.greenstone.gatherer.WGet;
52import org.greenstone.gatherer.file.WorkspaceTree;
53import org.greenstone.gatherer.util.StaticStrings;
54import org.greenstone.gatherer.util.Utility;
55
56/**
57 * @author John Thompson, Greenstone Digital Library, University of Waikato
58 * @version 2.1
59 */
60public class DownloadPane
61 extends JPanel {
62
63 /** The threshold for when the advanced options get added */
64 static private final int THRESHOLD = Configuration.SYSTEMS_MODE;
65
66 private boolean download_button_enabled = false;
67 private boolean ready = false;
68 private int current_mode;
69 private JButton clear_cache_button;
70 private JButton download_button;
71 private JCheckBox higher_checkbox;
72 private JCheckBox requisite_checkbox;
73 private JCheckBox same_host_checkbox;
74 private JScrollPane list_scroll;
75 private JComboBox depth_combobox;
76 private JPanel options_pane;
77 private JTextField url_field;
78 private Vector depth_model;
79 private WGet getter;
80
81 public DownloadPane() {
82 super();
83 // Create a new wget thread
84 getter = new WGet();
85 getter.start();
86 // And retrieve its list of pending jobs
87 list_scroll = getter.getDownloadJobList();
88
89 current_mode = Configuration.getMode();
90 // String user_dir = System.getProperty("user.dir"); // ****
91 // System.err.println("**** user dir = "+user_dir);
92 // Create
93 JPanel edit_pane = new JPanel();
94 JPanel details_pane = new JPanel();
95 options_pane = new JPanel();
96
97 JPanel url_pane = new JPanel();
98 JLabel url_label = new JLabel();
99 Dictionary.registerText(url_label, "Mirroring.Source_URL");
100 url_field = new JTextField();
101 Dictionary.registerTooltip(url_field, "Mirroring.Source_URL_Tooltip");
102
103 depth_model = new Vector();
104 depth_model.add(new DepthEntry(0, Dictionary.get("Mirroring.Download_Depth.Zero")));
105 /* @todo - add to dictionary */
106 depth_model.add(new DepthEntry(1, String.valueOf(1)));
107 /* @todo - add to dictionary */
108 depth_model.add(new DepthEntry(2, String.valueOf(2)));
109 /* @todo - add to dictionary */
110 depth_model.add(new DepthEntry(3, String.valueOf(3)));
111 /* @todo - add to dictionary */
112 depth_model.add(new DepthEntry(4, String.valueOf(4)));
113 /* @todo - add to dictionary */
114 depth_model.add(new DepthEntry(5, String.valueOf(5)));
115 depth_model.add(new DepthEntry(-1, Dictionary.get("Mirroring.Download_Depth.Unlimited")));
116 JPanel depth_pane = new JPanel();
117 JLabel depth_label = new JLabel();
118 Dictionary.registerText(depth_label, "Mirroring.Download_Depth");
119 depth_combobox = new JComboBox(depth_model);
120 Dictionary.registerTooltip(depth_combobox, "Mirroring.Download_Depth_Tooltip");
121
122 requisite_checkbox = new JCheckBox();
123 Dictionary.registerText(requisite_checkbox, "Mirroring.Download_Embedded");
124
125
126 higher_checkbox = new JCheckBox();
127 Dictionary.registerText(higher_checkbox, "Mirroring.Higher_Directories");
128 higher_checkbox.addActionListener(new CheckboxClickListener());
129
130 same_host_checkbox = new JCheckBox();
131 same_host_checkbox.setSelected(true);
132 Dictionary.registerText(same_host_checkbox, "Mirroring.Same_Host");
133
134 JPanel button_pane = new JPanel();
135
136 JButton preferences_button = new GLIButton();
137 preferences_button.setEnabled(true);
138 preferences_button.setMnemonic(KeyEvent.VK_P);
139 Dictionary.registerBoth(preferences_button, "Mirroring.Preferences", "Mirroring.Preferences_Tooltip");
140
141 clear_cache_button = new GLIButton();
142 clear_cache_button.setEnabled(true);
143 clear_cache_button.setMnemonic(KeyEvent.VK_C);
144 Dictionary.registerBoth(clear_cache_button, "Mirroring.ClearCache", "Mirroring.ClearCache_Tooltip");
145
146 download_button = new GLIButton();
147 download_button.setEnabled(true);
148 download_button.setMnemonic(KeyEvent.VK_D);
149 Dictionary.registerBoth(download_button, "Mirroring.Download", "Mirroring.Download_Tooltip");
150 // Connect
151 clear_cache_button.addActionListener(new ClearCacheListener());
152 download_button.addActionListener(new DownloadButtonListener());
153 preferences_button.addActionListener(new PreferencesButtonActionListener());
154
155 // Layout
156 url_pane.setLayout(new BorderLayout(5,0));
157 url_pane.add(url_label, BorderLayout.WEST);
158 url_pane.add(url_field, BorderLayout.CENTER);
159
160 depth_pane.setLayout(new GridLayout(1,3));
161 depth_pane.add(depth_label);
162 depth_pane.add(new JPanel());
163 depth_pane.add(depth_combobox);
164
165 details_pane.setLayout(new GridLayout(2,1,0,5));
166 details_pane.setBorder(BorderFactory.createEmptyBorder(2,2,5,2));
167 details_pane.add(url_pane);
168 details_pane.add(depth_pane);
169
170 options_pane.setLayout(new GridLayout(3,1,0,5));
171
172 options_pane.add(higher_checkbox);
173 options_pane.add(same_host_checkbox);
174 if (current_mode >= THRESHOLD) {
175 options_pane.add(requisite_checkbox);
176 }
177
178 button_pane.setLayout(new GridLayout(3,1));
179 button_pane.add(preferences_button);
180 button_pane.add(clear_cache_button);
181 button_pane.add(download_button);
182
183 edit_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(2,0,0,0), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("Mirroring.Download_Controls")), BorderFactory.createEmptyBorder(2,2,2,2))));
184 edit_pane.setLayout(new BorderLayout());
185 edit_pane.add(details_pane, BorderLayout.NORTH);
186 edit_pane.add(button_pane, BorderLayout.EAST);
187 edit_pane.add(options_pane, BorderLayout.CENTER);
188
189 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
190 setLayout(new BorderLayout());
191 add(edit_pane, BorderLayout.NORTH);
192 add(list_scroll, BorderLayout.CENTER);
193 }
194
195 public void afterDisplay() {
196 ready = true;
197 }
198
199
200 /** This method is called whenever the Download pane is brought into focus and is a good time to display a warning message if WGet is not available or of an older, problematic, version.
201 */
202 public void gainFocus() {
203 if(!ready) {
204 return;
205 }
206 // Lets see what warning message we should display, if any.
207 String wget_version_str = Configuration.getWGetVersion();
208 if(wget_version_str.equals(StaticStrings.NO_WGET_STR)) {
209 // If there was no WGet available then downloading is disabled entirely
210 download_button_enabled = false;
211 // And we tell the user why.
212 Gatherer.missingWGET();
213 }
214 else if(wget_version_str.equals(StaticStrings.WGET_OLD_STR)) {
215 // Downloading is enabled
216 download_button_enabled = true;
217 // But we display a preventable warning message about the path problems.
218 Gatherer.oldWGET();
219 }
220 // Otherwise version must be ok
221 else {
222 download_button_enabled = true;
223 }
224 // It is also a good time to determine if the download should be enabled - ie if its allowed to be enabled and a valid URL is present in the field.
225 download_button.setEnabled(download_button_enabled);
226 }
227
228 public void modeChanged(int mode) {
229 int old_mode = current_mode;
230 current_mode = mode;
231 if (old_mode >= THRESHOLD && current_mode >= THRESHOLD) {
232 return;
233 }
234 if (old_mode < THRESHOLD && current_mode < THRESHOLD) {
235 return;
236 }
237 if (current_mode >= THRESHOLD) {
238 options_pane.add(requisite_checkbox);
239 }
240 else {
241 options_pane.remove(requisite_checkbox);
242 requisite_checkbox.setSelected(false);
243 }
244 }
245
246
247 public void refresh(int refresh_reason, boolean ready)
248 {
249 }
250
251
252 /** A DepthEntry contains a depth value, as an int, and a representitive text string. This allows for a more meaningful appearance than '0' for instance. */
253 private class DepthEntry
254 implements Comparable {
255 private int value;
256 private String text;
257 /** Default constructor.
258 * @param value the depth value as an int
259 * @param text how this entry show represent itself as a String
260 */
261 public DepthEntry(int value, String text) {
262 this.text = text;
263 this.value = value;
264 }
265 /** Determines the natural ordering of this DepthEntry and some other object
266 * @param object the Object to test for ordering
267 * @return >0 if the object is before this one, 0 if they are equal, or <0 if the object is after this one
268 */
269 public int compareTo(Object object) {
270 // If the object is a DepthEntry then this is easy pesy.
271 if(object instanceof DepthEntry) {
272 int target_value = ((DepthEntry) object).getValue();
273 return value - target_value;
274 }
275 // If the object is a String, then we should try parsing an int from it
276 if(object instanceof String) {
277 try {
278 int target_value = Integer.parseInt((String)object);
279 return value - target_value;
280 }
281 catch(Exception exception) {
282 }
283 }
284 // Otherwise we'll try a string comparison between our text and the toString of the object
285 return text.compareTo(object.toString());
286 }
287
288 /** Determine if this DepthEntry is equal to some other object. Given that there is significant processing involved we push the resposiblility for this onto compareTo, so we only have the complex code once.
289 * @param object the Object to test for equality
290 * @return true if the object is equal to this depth entry, false otherwise
291 */
292 public boolean equals(Object object) {
293 return (compareTo(object) == 0);
294 }
295
296 public int getValue() {
297 return value;
298 }
299
300 public String toString() {
301 return text;
302 }
303 }
304
305 private class ClearCacheListener
306 implements ActionListener {
307 public void actionPerformed(ActionEvent event) {
308 // Retrieve the cache folder and delete it.
309 Utility.delete(Gatherer.getGLIUserCacheDirectoryPath());
310 // ...and refresh the node in the workspace tree to show it's all gone
311 Gatherer.g_man.refreshWorkspaceTree(WorkspaceTree.DOWNLOADED_FILES_CHANGED);
312 }
313 }
314
315 private class CheckboxClickListener
316 implements ActionListener {
317 public void actionPerformed(ActionEvent event) {
318 if (higher_checkbox.isSelected()) {
319 same_host_checkbox.setEnabled(false);
320 } else {
321 same_host_checkbox.setEnabled(true);
322 }
323 }
324 }
325
326 private class DownloadButtonListener
327 implements ActionListener {
328
329 public void actionPerformed(ActionEvent event) {
330 // Retrieve the current url and confirm it is valid
331 String url_str = url_field.getText();
332 URL url = null;
333 try {
334 url = new URL(url_str);
335 }
336 catch(MalformedURLException error) {
337 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Mirroring.Invalid_URL"), Dictionary.get("Mirroring.Invalid_URL_Title"), JOptionPane.ERROR_MESSAGE);
338 }
339
340 // Otherwise construct a new download job
341 Object depth_object = depth_combobox.getSelectedItem();
342 int depth_value = 0;
343 if(depth_object instanceof DepthEntry) {
344 depth_value = ((DepthEntry)depth_object).getValue();
345 }
346 else if(depth_object instanceof String) {
347 String depth_string = (String) depth_object;
348 try {
349 depth_value = Integer.parseInt(depth_string);
350 // Create a new entry for the purposes of comparison, and if needs be, addition
351 DepthEntry new_entry = new DepthEntry(depth_value, depth_string);
352 // Try to select the correct item from the combobox
353 depth_combobox.setSelectedItem(null);
354 depth_combobox.setSelectedItem(new_entry);
355 // We can see if that worked, and if it didn't add the entry
356 if(depth_combobox.getSelectedItem() == null) {
357 depth_combobox.addItem(new_entry);
358 depth_combobox.setSelectedItem(new_entry);
359 }
360 new_entry = null;
361 }
362 catch(Exception exception) {
363 /* @todo - add to dictionary */
364 JOptionPane.showMessageDialog(Gatherer.g_man, "Mirroring.Mirror_Depth.Invalid_Depth", "Mirroring.Mirror_Depth.Invalid_Depth_Title", JOptionPane.ERROR_MESSAGE);
365 return;
366 }
367 depth_string = null;
368 }
369 depth_object = null;
370
371 String destination_file_path = Gatherer.getGLIUserCacheDirectoryPath();
372 (new File(destination_file_path)).mkdirs(); // If they aren't already
373
374 if(url != null) {
375 getter.newDownloadJob(higher_checkbox.isSelected(), (higher_checkbox.isSelected()? false : !same_host_checkbox.isSelected()), !requisite_checkbox.isSelected(), url, depth_value, destination_file_path);
376 }
377 }
378 }
379
380 private class PreferencesButtonActionListener
381 implements ActionListener {
382 public void actionPerformed(ActionEvent event) {
383 new Preferences(Preferences.CONNECTION_PREFS);
384 }
385 }
386}
Note: See TracBrowser for help on using the repository browser.