source: trunk/gli/src/org/greenstone/gatherer/gui/MirrorPane.java@ 8353

Last change on this file since 8353 was 8353, checked in by mdewsnip, 20 years ago

Changed the collectionChanged() functions to refresh(), and added an extra parameter for more control over refreshing.

  • Property svn:keywords set to Author Date Id Revision
File size: 13.6 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.FileNode;
53import org.greenstone.gatherer.gui.tree.WorkspaceTree;
54import org.greenstone.gatherer.util.StaticStrings;
55import org.greenstone.gatherer.util.Utility;
56
57/**
58 * @author John Thompson, Greenstone Digital Library, University of Waikato
59 * @version 2.1
60 */
61public class MirrorPane
62 extends JPanel {
63
64 /** The threshold for when the advanced options get added */
65 static private final int THRESHOLD = Configuration.SYSTEMS_MODE;
66
67 private boolean download_button_enabled = false;
68 private boolean ready = false;
69 private int current_mode;
70 private JButton clear_cache_button;
71 private JButton download_button;
72 private JCheckBox higher_checkbox;
73 private JCheckBox requisite_checkbox;
74 private JCheckBox same_host_checkbox;
75 private JScrollPane list_scroll;
76 private JComboBox depth_combobox;
77 private JPanel options_pane;
78 private JTextField url_field;
79 private Vector depth_model;
80 private WGet getter;
81
82 public MirrorPane() {
83 super();
84 // Create a new wget thread
85 getter = new WGet();
86 getter.start();
87 // And retrieve its list of pending jobs
88 list_scroll = getter.getDownloadJobList();
89
90 current_mode = Configuration.getMode();
91 // String user_dir = System.getProperty("user.dir"); // ****
92 // System.err.println("**** user dir = "+user_dir);
93 // Create
94 JPanel edit_pane = new JPanel();
95 JPanel details_pane = new JPanel();
96 options_pane = new JPanel();
97
98 JPanel url_pane = new JPanel();
99 JLabel url_label = new JLabel();
100 Dictionary.registerText(url_label, "Mirroring.Source_URL");
101 url_field = new JTextField();
102 Dictionary.registerTooltip(url_field, "Mirroring.Source_URL_Tooltip");
103
104 depth_model = new Vector();
105 depth_model.add(new DepthEntry(0, Dictionary.get("Mirroring.Download_Depth.Zero")));
106 /* @todo - add to dictionary */
107 depth_model.add(new DepthEntry(1, String.valueOf(1)));
108 /* @todo - add to dictionary */
109 depth_model.add(new DepthEntry(2, String.valueOf(2)));
110 /* @todo - add to dictionary */
111 depth_model.add(new DepthEntry(3, String.valueOf(3)));
112 /* @todo - add to dictionary */
113 depth_model.add(new DepthEntry(4, String.valueOf(4)));
114 /* @todo - add to dictionary */
115 depth_model.add(new DepthEntry(5, String.valueOf(5)));
116 depth_model.add(new DepthEntry(-1, Dictionary.get("Mirroring.Download_Depth.Unlimited")));
117 JPanel depth_pane = new JPanel();
118 JLabel depth_label = new JLabel();
119 Dictionary.registerText(depth_label, "Mirroring.Download_Depth");
120 depth_combobox = new JComboBox(depth_model);
121 Dictionary.registerTooltip(depth_combobox, "Mirroring.Download_Depth_Tooltip");
122
123 requisite_checkbox = new JCheckBox();
124 Dictionary.registerText(requisite_checkbox, "Mirroring.Download_Embedded");
125
126
127 higher_checkbox = new JCheckBox();
128 Dictionary.registerText(higher_checkbox, "Mirroring.Higher_Directories");
129 higher_checkbox.addActionListener(new CheckboxClickListener());
130
131 same_host_checkbox = new JCheckBox();
132 same_host_checkbox.setSelected(true);
133 Dictionary.registerText(same_host_checkbox, "Mirroring.Same_Host");
134
135 JPanel button_pane = new JPanel();
136
137 JButton preferences_button = new GLIButton();
138 preferences_button.setEnabled(true);
139 preferences_button.setMnemonic(KeyEvent.VK_P);
140 Dictionary.registerBoth(preferences_button, "Mirroring.Preferences", "Mirroring.Preferences_Tooltip");
141
142 clear_cache_button = new GLIButton();
143 clear_cache_button.setEnabled(true);
144 clear_cache_button.setMnemonic(KeyEvent.VK_C);
145 Dictionary.registerBoth(clear_cache_button, "Mirroring.ClearCache", "Mirroring.ClearCache_Tooltip");
146
147 download_button = new GLIButton();
148 download_button.setEnabled(true);
149 download_button.setMnemonic(KeyEvent.VK_D);
150 Dictionary.registerBoth(download_button, "Mirroring.Download", "Mirroring.Download_Tooltip");
151 // Connect
152 clear_cache_button.addActionListener(new ClearCacheListener());
153 download_button.addActionListener(new DownloadButtonListener());
154 preferences_button.addActionListener(new PreferencesButtonActionListener());
155
156 // Layout
157 url_pane.setLayout(new BorderLayout(5,0));
158 url_pane.add(url_label, BorderLayout.WEST);
159 url_pane.add(url_field, BorderLayout.CENTER);
160
161 depth_pane.setLayout(new GridLayout(1,3));
162 depth_pane.add(depth_label);
163 depth_pane.add(new JPanel());
164 depth_pane.add(depth_combobox);
165
166 details_pane.setLayout(new GridLayout(2,1,0,5));
167 details_pane.setBorder(BorderFactory.createEmptyBorder(2,2,5,2));
168 details_pane.add(url_pane);
169 details_pane.add(depth_pane);
170
171 options_pane.setLayout(new GridLayout(3,1,0,5));
172
173 options_pane.add(higher_checkbox);
174 options_pane.add(same_host_checkbox);
175 if (current_mode >= THRESHOLD) {
176 options_pane.add(requisite_checkbox);
177 }
178
179 button_pane.setLayout(new GridLayout(3,1));
180 button_pane.add(preferences_button);
181 button_pane.add(clear_cache_button);
182 button_pane.add(download_button);
183
184 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))));
185 edit_pane.setLayout(new BorderLayout());
186 edit_pane.add(details_pane, BorderLayout.NORTH);
187 edit_pane.add(button_pane, BorderLayout.EAST);
188 edit_pane.add(options_pane, BorderLayout.CENTER);
189
190 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
191 setLayout(new BorderLayout());
192 add(edit_pane, BorderLayout.NORTH);
193 add(list_scroll, BorderLayout.CENTER);
194 }
195
196 public void afterDisplay() {
197 ready = true;
198 }
199
200
201 /** This method is called whenever the Mirror 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.
202 */
203 public void gainFocus() {
204 if(!ready) {
205 return;
206 }
207 // Lets see what warning message we should display, if any.
208 String wget_version_str = Configuration.getWGetVersion();
209 if(wget_version_str.equals(StaticStrings.NO_WGET_STR)) {
210 // If there was no WGet available then downloading is disabled entirely
211 download_button_enabled = false;
212 // And we tell the user why.
213 Gatherer.missingWGET();
214 }
215 else if(wget_version_str.equals(StaticStrings.WGET_OLD_STR)) {
216 // Downloading is enabled
217 download_button_enabled = true;
218 // But we display a preventable warning message about the path problems.
219 Gatherer.oldWGET();
220 }
221 // Otherwise version must be ok
222 else {
223 download_button_enabled = true;
224 }
225 // 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.
226 download_button.setEnabled(download_button_enabled);
227 }
228
229 public void modeChanged(int mode) {
230 int old_mode = current_mode;
231 current_mode = mode;
232 if (old_mode >= THRESHOLD && current_mode >= THRESHOLD) {
233 return;
234 }
235 if (old_mode < THRESHOLD && current_mode < THRESHOLD) {
236 return;
237 }
238 if (current_mode >= THRESHOLD) {
239 options_pane.add(requisite_checkbox);
240 }
241 else {
242 options_pane.remove(requisite_checkbox);
243 requisite_checkbox.setSelected(false);
244 }
245 }
246
247
248 public void refresh(int refresh_reason, boolean ready)
249 {
250 }
251
252
253 /** 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. */
254 private class DepthEntry
255 implements Comparable {
256 private int value;
257 private String text;
258 /** Default constructor.
259 * @param value the depth value as an int
260 * @param text how this entry show represent itself as a String
261 */
262 public DepthEntry(int value, String text) {
263 this.text = text;
264 this.value = value;
265 }
266 /** Determines the natural ordering of this DepthEntry and some other object
267 * @param object the Object to test for ordering
268 * @return >0 if the object is before this one, 0 if they are equal, or <0 if the object is after this one
269 */
270 public int compareTo(Object object) {
271 // If the object is a DepthEntry then this is easy pesy.
272 if(object instanceof DepthEntry) {
273 int target_value = ((DepthEntry) object).getValue();
274 return value - target_value;
275 }
276 // If the object is a String, then we should try parsing an int from it
277 if(object instanceof String) {
278 try {
279 int target_value = Integer.parseInt((String)object);
280 return value - target_value;
281 }
282 catch(Exception exception) {
283 }
284 }
285 // Otherwise we'll try a string comparison between our text and the toString of the object
286 return text.compareTo(object.toString());
287 }
288
289 /** 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.
290 * @param object the Object to test for equality
291 * @return true if the object is equal to this depth entry, false otherwise
292 */
293 public boolean equals(Object object) {
294 return (compareTo(object) == 0);
295 }
296
297 public int getValue() {
298 return value;
299 }
300
301 public String toString() {
302 return text;
303 }
304 }
305
306 private class ClearCacheListener
307 implements ActionListener {
308 public void actionPerformed(ActionEvent event) {
309 // Retrieve the cache folder and delete it.
310 Utility.delete(Utility.getCacheDir());
311 // ...and refresh the node in the workspace tree to show it's all gone
312 Gatherer.g_man.refreshWorkspaceTree(WorkspaceTree.DOWNLOADED_FILES_CHANGED);
313 }
314 }
315
316 private class CheckboxClickListener
317 implements ActionListener {
318 public void actionPerformed(ActionEvent event) {
319 if (higher_checkbox.isSelected()) {
320 same_host_checkbox.setEnabled(false);
321 } else {
322 same_host_checkbox.setEnabled(true);
323 }
324 }
325 }
326
327 private class DownloadButtonListener
328 implements ActionListener {
329
330 public void actionPerformed(ActionEvent event) {
331 // Retrieve the current url and confirm it is valid
332 String url_str = url_field.getText();
333 URL url = null;
334 try {
335 url = new URL(url_str);
336 }
337 catch(MalformedURLException error) {
338 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Mirroring.Invalid_URL"), Dictionary.get("Mirroring.Invalid_URL_Title"), JOptionPane.ERROR_MESSAGE);
339 }
340
341 // Otherwise construct a new download job
342 Object depth_object = depth_combobox.getSelectedItem();
343 int depth_value = 0;
344 if(depth_object instanceof DepthEntry) {
345 depth_value = ((DepthEntry)depth_object).getValue();
346 }
347 else if(depth_object instanceof String) {
348 String depth_string = (String) depth_object;
349 try {
350 depth_value = Integer.parseInt(depth_string);
351 // Create a new entry for the purposes of comparison, and if needs be, addition
352 DepthEntry new_entry = new DepthEntry(depth_value, depth_string);
353 // Try to select the correct item from the combobox
354 depth_combobox.setSelectedItem(null);
355 depth_combobox.setSelectedItem(new_entry);
356 // We can see if that worked, and if it didn't add the entry
357 if(depth_combobox.getSelectedItem() == null) {
358 depth_combobox.addItem(new_entry);
359 depth_combobox.setSelectedItem(new_entry);
360 }
361 new_entry = null;
362 }
363 catch(Exception exception) {
364 /* @todo - add to dictionary */
365 JOptionPane.showMessageDialog(Gatherer.g_man, "Mirroring.Mirror_Depth.Invalid_Depth", "Mirroring.Mirror_Depth.Invalid_Depth_Title", JOptionPane.ERROR_MESSAGE);
366 return;
367 }
368 depth_string = null;
369 }
370 depth_object = null;
371
372 File destination_file = Utility.getCacheDir();
373 destination_file.mkdirs(); // If they aren't already
374 String destination_filename = destination_file.getAbsolutePath();
375 if(!destination_filename.endsWith(File.separator)) {
376 destination_filename = destination_filename + File.separator;
377 }
378
379 if(url != null) {
380 getter.newDownloadJob(higher_checkbox.isSelected(), (higher_checkbox.isSelected()? false : !same_host_checkbox.isSelected()), !requisite_checkbox.isSelected(), url, depth_value, destination_filename);
381 }
382 }
383 }
384
385 private class PreferencesButtonActionListener
386 implements ActionListener {
387 public void actionPerformed(ActionEvent event) {
388 new Preferences(Preferences.CONNECTION_PREFS);
389 }
390 }
391}
Note: See TracBrowser for help on using the repository browser.