source: trunk/gli/src/org/greenstone/gatherer/gui/GatherPane.java@ 11662

Last change on this file since 11662 was 11651, checked in by mdewsnip, 18 years ago

Removed another piece of unused code now that there is only one collection tree. This code was also causing the client or applet versions of the GLI to crash.

  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 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.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.event.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.Configuration;
47import org.greenstone.gatherer.DebugStream;
48import org.greenstone.gatherer.Dictionary;
49import org.greenstone.gatherer.Gatherer;
50import org.greenstone.gatherer.collection.CollectionTree;
51import org.greenstone.gatherer.collection.CollectionTreeNode;
52import org.greenstone.gatherer.file.FileNode;
53import org.greenstone.gatherer.file.FileOpenActionListener;
54import org.greenstone.gatherer.file.FileQueue;
55import org.greenstone.gatherer.file.FileSystemModel;
56import org.greenstone.gatherer.file.RecycleBin;
57import org.greenstone.gatherer.file.WorkspaceTree;
58import org.greenstone.gatherer.file.WorkspaceTreeNode;
59import org.greenstone.gatherer.gui.tree.DragTree;
60import org.greenstone.gatherer.gui.ExplodeMetadataPrompt;
61import org.greenstone.gatherer.util.DragComponent;
62import org.greenstone.gatherer.util.DragGroup;
63import org.greenstone.gatherer.util.JarTools;
64import org.greenstone.gatherer.util.Utility;
65
66
67/** The collection pane is analogous with a file manager. It is there that the user chooses which files to include in their collection and what structure the file hierarchy should take. The later aspect is not important for the Greenstone Suite, but is usefull for grouping files for ease of metadata markup. The view essentially consists of two file trees, one denoting the entire source workspace and the other the files within your collection. The trees themselves have a title bar at the top, a filter control at the bottom, and are coloured to indicate activity (grey for disabled). The remainder of the screen is taken by a status area, to indicate current file job progress during copying etc, and three buttons for controlling features of the view.
68 * @author John Thompson, Greenstone Digital Library, University of Waikato
69 * @version 2.3
70 */
71public class GatherPane
72 extends JPanel
73 implements ActionListener
74{
75 /** The group encompassing all of the components available as drop targets for drag and drop actions. Required so that only one component renders the ghost and higlights itself as a target, which the other members are restored to their original, pristine, condition. */
76 private DragGroup group = null;
77 /** The tree showing the files within the collection. */
78 private CollectionTree collection_tree = null;
79 /** The threaded queue that handles the actually movement of files, so that the gui remains responsive. */
80 private FileQueue file_queue = null;
81 /** The filter currently applied to the collection tree. */
82 private Filter collection_filter = null;
83 /** The filter currently applied to the workspace tree. */
84 private Filter workspace_filter = null;
85 /** The button used to cancel all pending file queue jobs. */
86 private JButton stop_action = null;
87 /** The button used to create a new folder in the collection tree. */
88 private JButton new_folder = null;
89 /** The label shown at the top of the collection tree. */
90 private JLabel collection_label = null;
91 /** The label shown in the status area explaining the file apon which action is taking place. */
92 private JLabel filename_label = null;
93 /** The label shown explaining the current state of the file queue thread. */
94 private JLabel status_label = null;
95 /** The label at the top of the workspace tree. */
96 private JLabel workspace_label = null;
97 /** The panel that contains the collection tree. */
98 private JPanel collection_pane = null;
99 /** The panel that contains the various controls including the status area. */
100 private JPanel control_pane = null;
101 /** The panel that contains the workspace tree. */
102 private JPanel workspace_pane = null;
103 /** The scrollable area into which the collection tree is placed. */
104 private JScrollPane collection_scroll = null;
105 /** The scrollable area into which the workspace tree is placed. */
106 private JScrollPane workspace_scroll = null;
107 /** A split pane seperating the two trees, allowing for the screen real-estate for each to be changed. */
108 private JSplitPane tree_pane = null;
109 /** The minimum size a gui component can become. */
110 static private Dimension MIN_SIZE = new Dimension( 90, 90);
111 /** The default size of the status area. */
112 static private Dimension STATUS_SIZE = new Dimension(450, 120);
113 /** The initial size of the trees. */
114 static private Dimension TREE_SIZE = new Dimension(400, 430);
115
116 /** The tree showing the available source workspace. */
117 public WorkspaceTree workspace_tree = null;
118
119
120 public GatherPane()
121 {
122 this.group = new DragGroup();
123 this.file_queue = Gatherer.f_man.getQueue();
124
125 // Create components.
126 stop_action = new GLIButton();
127 stop_action.addActionListener(this);
128 stop_action.setEnabled(false);
129 stop_action.setMnemonic(KeyEvent.VK_S);
130 file_queue.registerStopButton(stop_action);
131 Dictionary.registerBoth(stop_action, "Collection.Stop", "Collection.Stop_Tooltip");
132
133 new_folder = new GLIButton(JarTools.getImage("folder.gif"));
134 new_folder.addActionListener(this);
135 new_folder.setEnabled(false);
136 new_folder.setMinimumSize(MIN_SIZE);
137 new_folder.setMnemonic(KeyEvent.VK_N);
138 new_folder.setPreferredSize(MIN_SIZE);
139 Dictionary.registerTooltip(new_folder, "Collection.New_Folder_Tooltip");
140 }
141
142 /** Any implementation of ActionListener requires this method so that when an action is performed the appropriate effect can occur. In this case there are three valid possibilities. If the action occured on the recycle bin, then delete the current selection from the collection tree. If the action instead occured on the new folder button, then create a new folder under the current (single) selection in the collection tree. And finally if the cancel button was pressed, cancel the current, and remaining, jobs on the file queue. */
143 public void actionPerformed(ActionEvent event) {
144 // If a user has clicked on the bin button directly remove whatever
145 // files are selected in the active tree.
146 if (event.getSource() == Gatherer.recycle_bin) {
147 if (!Gatherer.recycle_bin.ignore()) {
148 // Find the active tree (you've made selections in).
149 DragTree tree = (DragTree) group.getActive();
150 // Fudge things a bit
151 group.setSource(tree);
152 // Determine the selection.
153 TreePath paths[] = tree.getSelectionPaths();
154 if(paths != null) {
155 FileNode[] source_nodes = new FileNode[paths.length];
156 for(int i = 0; i < paths.length; i++) {
157 source_nodes[i] = (FileNode)(paths[i].getLastPathComponent());
158 }
159 Gatherer.f_man.action(tree, source_nodes, Gatherer.recycle_bin, null);
160 }
161 }
162 }
163 // If a user has clicked on new_folder create a new folder under
164 // whatever node is selected.
165 else if(event.getSource() == new_folder && collection_tree != null) {
166 int count = collection_tree.getSelectionCount();
167 boolean error = false;
168 if(count == 1) {
169 TreePath path = collection_tree.getSelectionPath();
170 CollectionTreeNode node = (CollectionTreeNode) path.getLastPathComponent();
171 if (node.getAllowsChildren()) {
172 Gatherer.f_man.newFolder(collection_tree, node);
173 }
174 else {
175 // try the parent
176 CollectionTreeNode parent = (CollectionTreeNode) node.getParent();
177 if (parent!=null && parent.getAllowsChildren()) {
178 Gatherer.f_man.newFolder(collection_tree, parent);
179 } else {
180 error = true;
181 }
182 }
183 }
184 else {
185 error = true;
186 }
187 if(error) {
188 // instead of an error, we now create a new folder at the root
189 CollectionTreeNode node = (CollectionTreeNode) collection_tree.getModel().getRoot();
190 Gatherer.f_man.newFolder(collection_tree, node);
191 }
192 }
193 else if(event.getSource() == stop_action) {
194 file_queue.cancelAction();
195 }
196 }
197
198
199 /** Generates the pane on controls used to 'collect' files into the collection. Resposible for creating, connecting and laying out these controls. */
200 public void display()
201 {
202 // Workspace Tree
203 workspace_pane = new JPanel();
204 workspace_pane.setMinimumSize(MIN_SIZE);
205 workspace_pane.setPreferredSize(TREE_SIZE);
206 workspace_pane.setSize(TREE_SIZE);
207
208 workspace_label = new JLabel();
209 workspace_label.setOpaque(true);
210 workspace_label.setBackground(Configuration.getColor("coloring.workspace_heading_background", false));
211 workspace_label.setForeground(Configuration.getColor("coloring.workspace_heading_foreground", false));
212 Dictionary.registerText(workspace_label, "Collection.Workspace");
213
214 workspace_tree = new WorkspaceTree();
215 group.add(workspace_tree);
216 workspace_scroll = new JScrollPane(workspace_tree);
217 workspace_filter = workspace_tree.getFilter();
218
219 // Collection Tree
220 collection_pane = new JPanel();
221 collection_pane.setMinimumSize(MIN_SIZE);
222 collection_pane.setPreferredSize(TREE_SIZE);
223 collection_pane.setSize(TREE_SIZE);
224
225 collection_label = new JLabel();
226 collection_label.setOpaque(true);
227 Dictionary.registerText(collection_label, "Collection.No_Collection");
228
229 collection_tree = Gatherer.c_man.getCollectionTree();
230 collection_tree.setEnabled(Gatherer.c_man.getCollectionTreeModel() != null);
231 group.add(collection_tree);
232 collection_filter = collection_tree.getFilter();
233
234 tree_pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
235
236 // Status pane
237 control_pane = new JPanel();
238
239 JPanel inner_pane = new JPanel();
240 inner_pane.setSize(STATUS_SIZE);
241
242 JPanel file_pane = new JPanel();
243 JPanel progress_pane = new JPanel();
244 JLabel file_status = file_queue.getFileStatus();
245
246 JProgressBar progress_bar = file_queue.getProgressBar();
247
248 JPanel button_pane = new JPanel();
249
250 RecycleBin recycle_bin = Gatherer.recycle_bin;
251 recycle_bin.addActionListener(this);
252 recycle_bin.setMinimumSize(MIN_SIZE);
253 recycle_bin.setPreferredSize(MIN_SIZE);
254 Dictionary.registerTooltip(recycle_bin, "Collection.Delete_Tooltip");
255 group.add(recycle_bin);
256
257 // Layout Components.
258 workspace_pane.setLayout(new BorderLayout());
259 workspace_pane.add(workspace_label, BorderLayout.NORTH);
260 workspace_pane.add(workspace_scroll, BorderLayout.CENTER);
261 workspace_pane.add(workspace_filter, BorderLayout.SOUTH);
262
263 collection_pane.setLayout(new BorderLayout());
264 collection_pane.add(collection_label, BorderLayout.NORTH);
265
266 tree_pane.add(workspace_pane, JSplitPane.LEFT);
267 tree_pane.add(collection_pane, JSplitPane.RIGHT);
268 tree_pane.setDividerLocation(TREE_SIZE.width - 10);
269
270 file_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
271 file_pane.setLayout(new BorderLayout());
272 file_pane.add(file_status, BorderLayout.CENTER);
273 file_pane.add(stop_action, BorderLayout.EAST);
274
275 progress_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
276 progress_pane.setLayout(new BorderLayout());
277 progress_pane.add(progress_bar, BorderLayout.CENTER);
278
279 inner_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10,10,10,10), BorderFactory.createLoweredBevelBorder()));
280 inner_pane.setLayout(new GridLayout(2,1));
281 inner_pane.add(file_pane);
282 inner_pane.add(progress_pane);
283
284 button_pane.add(new_folder);
285 button_pane.add(recycle_bin);
286
287 control_pane.setLayout(new BorderLayout());
288 control_pane.add(inner_pane, BorderLayout.CENTER);
289 control_pane.add(button_pane, BorderLayout.EAST);
290
291 this.setLayout(new BorderLayout());
292 this.add(tree_pane, BorderLayout.CENTER);
293 this.add(control_pane, BorderLayout.SOUTH);
294 }
295
296
297 /** Called to inform this control panel that it has just gained focus as an effect of the user clicking on its tab.
298 */
299 public void gainFocus()
300 {
301 // Add the collection tree and filter back into this pane
302 collection_scroll = new JScrollPane(collection_tree);
303 collection_pane.add(collection_scroll, BorderLayout.CENTER);
304 collection_pane.add(collection_filter, BorderLayout.SOUTH);
305 }
306
307
308 /** Called to inform this pane that it has just lost focus as an effect of the user clicking on another tab
309 */
310 public void loseFocus()
311 {
312 // Remove the collection tree and filter from this pane so it can be added to the Enrich pane
313 collection_pane.remove(collection_scroll);
314 collection_pane.remove(collection_filter);
315 }
316
317
318 /** Retrieve a list of the currently selected file records in the collection tree. */
319 private CollectionTreeNode[] getCollectionTreeSelection()
320 {
321 TreePath paths[] = collection_tree.getSelectionPaths();
322 CollectionTreeNode records[] = null;
323 if (paths != null) {
324 records = new CollectionTreeNode[paths.length];
325 for (int i = 0; i < records.length; i++) {
326 records[i] = (CollectionTreeNode) paths[i].getLastPathComponent();
327 }
328 }
329 return records;
330 }
331
332
333 /** Called whenever the detail mode changes to ensure the filters are at an appropriate level (ie only editable by those that understand regular expression matching)
334 * @param mode the mode level as an int
335 */
336 public void modeChanged(int mode) {
337 collection_filter.setEditable(mode > Configuration.LIBRARIAN_MODE);
338 workspace_filter.setEditable(mode > Configuration.LIBRARIAN_MODE);
339 }
340
341
342 /** Refresh this pane, depending on what has just happened (refresh_reason). */
343 public void refresh(int refresh_reason, boolean collection_loaded)
344 {
345 if (collection_loaded) {
346 // Update collection label
347 Dictionary.registerText(collection_label, "Collection.Collection");
348 collection_label.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
349 collection_label.setForeground(Configuration.getColor("coloring.collection_heading_foreground", false));
350
351 // Update collection tree
352 if (refresh_reason == Gatherer.COLLECTION_OPENED) {
353 collection_tree.setModel(Gatherer.c_man.getCollectionTreeModel());
354 }
355
356 // Update collection filter
357 collection_filter.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
358 }
359 else {
360 // Update collection label
361 String[] args = new String[1];
362 args[0] = Dictionary.get("Collection.No_Collection");
363 Dictionary.registerText(collection_label, "Collection.Collection", args);
364 collection_label.setBackground(Color.lightGray);
365 collection_label.setForeground(Color.black);
366
367 // Update collection tree
368 collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error")));
369
370 // Update collection filter
371 collection_filter.setBackground(Color.lightGray);
372 }
373
374 // Enable or disable the controls
375 workspace_tree.setEnabled(true);
376 collection_tree.setEnabled(collection_loaded);
377 collection_filter.setEnabled(collection_loaded);
378 new_folder.setEnabled(collection_loaded);
379 }
380
381
382 public void refreshCollectionTree(int refresh_reason) {
383 collection_tree.refresh(null);
384 }
385
386
387 public void refreshWorkspaceTree(int refresh_reason) {
388 workspace_tree.refresh(refresh_reason);
389 }
390}
Note: See TracBrowser for help on using the repository browser.