source: trunk/gli/src/org/greenstone/gatherer/file/WorkspaceTree.java@ 11622

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

Lots more object-orientation improvements to the collection and workspace trees.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1/**
2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 *
9 * Copyright (C) 2006 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *############################################################################
25 */
26
27package org.greenstone.gatherer.file;
28
29import java.awt.event.*;
30import java.io.File;
31import java.util.Enumeration;
32import javax.swing.*;
33import javax.swing.tree.TreePath;
34import org.greenstone.gatherer.Configuration;
35import org.greenstone.gatherer.DebugStream;
36import org.greenstone.gatherer.Dictionary;
37import org.greenstone.gatherer.Gatherer;
38import org.greenstone.gatherer.gui.CreateShortcutPrompt;
39import org.greenstone.gatherer.gui.tree.DragTree;
40
41
42public class WorkspaceTree
43 extends DragTree
44 implements MouseListener
45{
46 static public final int LIBRARY_CONTENTS_CHANGED = 10;
47 static public final int DOWNLOADED_FILES_CHANGED = 11;
48 static public final int FOLDER_SHORTCUTS_CHANGED = 12;
49
50
51 public WorkspaceTree()
52 {
53 super(WorkspaceTreeModel.getWorkspaceTreeModel(), true);
54 addMouseListener(this);
55
56 setBackgroundNonSelectionColor(Configuration.getColor("coloring.workspace_tree_background", false));
57 setBackgroundSelectionColor(Configuration.getColor("coloring.workspace_selection_background", false));
58 setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
59 setTextSelectionColor(Configuration.getColor("coloring.workspace_selection_foreground", false));
60
61 filter.setBackground(Configuration.getColor("coloring.workspace_heading_background", false));
62 filter.setEditable(Configuration.getMode() > Configuration.LIBRARIAN_MODE);
63 }
64
65
66 public void addDirectoryMapping(String name, File file)
67 {
68 // Update the information stored in the user's configuration
69 Configuration.addDirectoryMapping(name, file);
70
71 // Now update the tree
72 refresh(FOLDER_SHORTCUTS_CHANGED);
73 }
74
75
76 public boolean isDraggable()
77 {
78 return true;
79 }
80
81
82 public boolean isDroppable()
83 {
84 return false;
85 }
86
87
88 public void mouseClicked(MouseEvent event)
89 {
90 if (SwingUtilities.isRightMouseButton(event)) {
91 new WorkspaceTreeRightClickMenu(this, event);
92 }
93 }
94
95 public void mouseEntered(MouseEvent event) { }
96
97 public void mouseExited(MouseEvent event) { }
98
99 public void mousePressed(MouseEvent event) { }
100
101 public void mouseReleased(MouseEvent event) { }
102
103
104 public void refresh(int refresh_reason)
105 {
106 DebugStream.println("WorkspaceTree::refresh()... ");
107
108 // The method for displaying the tree has changed - redraw the tree
109 if (refresh_reason == DragTree.TREE_DISPLAY_CHANGED) {
110 DebugStream.println("...Reason: tree display changed.");
111 updateUI();
112 }
113
114 // The loaded collection has changed - currently do nothing
115 if (refresh_reason == DragTree.LOADED_COLLECTION_CHANGED) {
116 DebugStream.println("...Reason: loaded collection changed.");
117 }
118
119 // The collection's contents have changed - refresh collection's import folder
120 if (refresh_reason == DragTree.COLLECTION_CONTENTS_CHANGED) {
121 DebugStream.println("...Reason: collection contents changed.");
122 String collection_import_directory_path = Gatherer.c_man.getCollectionImportDirectoryPath();
123 refreshEveryNodeShowingFolder(collection_import_directory_path);
124 }
125
126 // The collections in the library have changed - refresh the collect directory
127 if (refresh_reason == WorkspaceTree.LIBRARY_CONTENTS_CHANGED) {
128 DebugStream.println("...Reason: library contents changed.");
129 String collect_directory_path = Gatherer.getCollectDirectoryPath();
130 refreshEveryNodeShowingFolder(collect_directory_path);
131 WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
132 }
133
134 // The downloaded files have changed - refresh that node
135 if (refresh_reason == WorkspaceTree.DOWNLOADED_FILES_CHANGED) {
136 DebugStream.println("...Reason: downloaded files changed.");
137 WorkspaceTreeModel.refreshDownloadedFilesNode();
138 }
139
140 // The folder shortcuts have changed - refresh only them
141 if (refresh_reason == WorkspaceTree.FOLDER_SHORTCUTS_CHANGED) {
142 DebugStream.println("...Reason: folder shortcuts changed.");
143 WorkspaceTreeModel.refreshFolderShortcuts();
144 }
145 }
146
147
148 private void refreshEveryNodeShowingFolder(String folder_path_str)
149 {
150 // Search through the expanded tree paths, checking if any show the given folder
151 TreePath tree_root_path = new TreePath(getModel().getRoot());
152 Enumeration expanded_tree_paths = getExpandedDescendants(tree_root_path);
153 while (expanded_tree_paths.hasMoreElements()) {
154 TreePath expanded_tree_path = (TreePath) expanded_tree_paths.nextElement();
155 WorkspaceTreeNode tree_node = (WorkspaceTreeNode) expanded_tree_path.getLastPathComponent();
156
157 File tree_node_file = tree_node.getFile();
158 if (tree_node_file == null) {
159 continue;
160 }
161
162 // Get the path of the open tree node
163 String tree_node_path_str = tree_node_file.toString();
164 if (!tree_node_path_str.endsWith(File.separator)) {
165 tree_node_path_str = tree_node_path_str + File.separator;
166 }
167
168 // If the specified folder is open, it must be refreshed
169 if (tree_node_path_str.equals(folder_path_str)) {
170 System.err.println("Must refresh node " + tree_node_path_str + "!");
171 ((WorkspaceTreeModel) getModel()).refresh(expanded_tree_path);
172 }
173 }
174 }
175
176
177 public void removeDirectoryMapping(WorkspaceTreeNode target)
178 {
179 // Update the information stored in the user's configuration
180 Configuration.removeDirectoryMapping(target.toString());
181
182 // Update tree
183 refresh(FOLDER_SHORTCUTS_CHANGED);
184 }
185
186
187 public String toString()
188 {
189 return "Workspace";
190 }
191
192
193 /** When a user right-clicks within the workspace and collection trees they are presented with a small popup menu of context based options. This class provides such functionality.
194 */
195 private class WorkspaceTreeRightClickMenu
196 extends JPopupMenu
197 implements ActionListener
198 {
199 /** The tree over which the right click action occurred. */
200 private WorkspaceTree workspace_tree = null;
201 /** The tree nodes selected when the right click action occurred. */
202 private TreePath[] selection_paths = null;
203 /** The file record over which the right click action occurred. */
204 private WorkspaceTreeNode node = null;
205
206 private JMenuItem create_shortcut = null;
207 private JMenuItem delete_shortcut = null;
208 private JMenuItem collapse_folder = null;
209 private JMenuItem expand_folder = null;
210 private JMenuItem explode_metadata_database = null;
211 private JMenuItem delete = null;
212 private JMenuItem metaaudit = null;
213 private JMenuItem new_folder = null;
214 private JMenuItem new_dummy_doc = null;
215 private JMenuItem open_externally = null;
216 private JMenuItem rename = null;
217 private JMenuItem replace = null;
218
219
220 private WorkspaceTreeRightClickMenu(WorkspaceTree workspace_tree, MouseEvent event)
221 {
222 super();
223 this.workspace_tree = workspace_tree;
224
225 // Note we have to use setImmediate() with the set selction paths
226 // otherwise the selection doesn't get updated until after the
227 // popup comes up.
228
229 // the right click position
230 TreePath right_click_path = workspace_tree.getPathForLocation(event.getX(), event.getY());
231 if (right_click_path == null) {
232 // user has clicked outside of the tree, clear the selection
233 selection_paths = null;
234 workspace_tree.setImmediate(true);
235 workspace_tree.clearSelection();
236 workspace_tree.setImmediate(false);
237 }
238 else {
239 // Get the paths currently selected in the tree
240 selection_paths = workspace_tree.getSelectionPaths();
241 if (selection_paths == null) {
242 // nothing currently selected - we shift the selection to
243 // the node that was right clicked on
244 selection_paths = new TreePath[1];
245 selection_paths[0] = right_click_path;
246 workspace_tree.setImmediate(true);
247 workspace_tree.setSelectionPath(right_click_path);
248 workspace_tree.setImmediate(false);
249 }
250 else if (selection_paths.length == 1 && ! selection_paths[0].equals( right_click_path)) {
251 workspace_tree.setImmediate(true);
252 workspace_tree.clearSelection();
253 workspace_tree.setSelectionPath(right_click_path);
254 workspace_tree.setImmediate(false);
255 selection_paths[0] = right_click_path;
256 }
257 else {
258 // we had multiply selected paths in the tree.
259 // if we clicked on one of those paths, then use all the
260 // current selection, otherwise clear the selection and
261 // select the one we right clicked on
262 boolean clicked_in_selection = false;
263 for (int i = 0; i < selection_paths.length; i++) {
264 if (selection_paths[i].equals(right_click_path)) {
265 clicked_in_selection = true;
266 break;
267 }
268 }
269 if (!clicked_in_selection) {
270 // want the tree to update right away
271 workspace_tree.setImmediate(true);
272 workspace_tree.clearSelection();
273 workspace_tree.setSelectionPath(right_click_path);
274 workspace_tree.setImmediate(false);
275 selection_paths = new TreePath[1];
276 selection_paths[0] = right_click_path;
277 }
278 }
279 }
280
281 // Create an appropriate context menu, based on what is selected
282 buildContextMenu(selection_paths);
283
284 // Show the popup menu on screen
285 show(workspace_tree, event.getX(), event.getY());
286 }
287
288
289 private void buildContextMenu(TreePath[] selection_paths)
290 {
291 // If nothing is selected, no options are available...
292 if (selection_paths == null) {
293 return;
294 }
295
296 // Only meta-audit and delete are available if multiple items are selected...
297 if (selection_paths.length > 1) {
298 return;
299 }
300
301 TreePath path = selection_paths[0];
302 node = (WorkspaceTreeNode) path.getLastPathComponent();
303
304 // ---- Options for file nodes ----
305 if (node.isLeaf()) {
306 // Open the file in an external program
307 open_externally = new JMenuItem(Dictionary.get("Menu.Open_Externally"), KeyEvent.VK_O);
308 open_externally.addActionListener(this);
309 add(open_externally);
310
311 return;
312 }
313
314 // ---- Options for folder nodes ----
315 // Collapse or expand, depending on current status
316 if (workspace_tree.isExpanded(path)) {
317 collapse_folder = new JMenuItem(Dictionary.get("Menu.Collapse"), KeyEvent.VK_C);
318 collapse_folder.addActionListener(this);
319 add(collapse_folder);
320 }
321 else {
322 expand_folder = new JMenuItem(Dictionary.get("Menu.Expand"), KeyEvent.VK_O);
323 expand_folder.addActionListener(this);
324 add(expand_folder);
325 }
326
327 // Create/remove shortcut option, for workspace tree only
328 if (workspace_tree == workspace_tree) {
329 // The "built-in" folders can't be modified
330 String node_name = node.toString();
331 if (node_name.equals(Dictionary.get("Tree.World")) || node_name.equals(Dictionary.get("Tree.Root")) || node_name.equals(Dictionary.get("Tree.DownloadedFiles"))) {
332 return;
333 }
334
335 // You can unmap 1st level nodes
336 WorkspaceTreeNode root = (WorkspaceTreeNode) workspace_tree.getModel().getRoot();
337 if (root.getIndex(node) != -1) {
338 delete_shortcut = new JMenuItem(Dictionary.get("MappingPrompt.Unmap"), KeyEvent.VK_R);
339 delete_shortcut.addActionListener(this);
340 add(delete_shortcut);
341 }
342 // Or map any other level directories
343 else {
344 create_shortcut = new JMenuItem(Dictionary.get("MappingPrompt.Map"), KeyEvent.VK_S);
345 create_shortcut.addActionListener(this);
346 add(create_shortcut);
347 }
348 }
349 }
350
351
352 /** Called whenever one of the menu items is clicked, this method then causes the appropriate effect. */
353 public void actionPerformed(ActionEvent event)
354 {
355 Object source = event.getSource();
356
357 // Create shortcut
358 if (source == create_shortcut) {
359 CreateShortcutPrompt csp = new CreateShortcutPrompt(workspace_tree, node.getFile());
360 csp.destroy();
361 }
362
363 // Delete shortcut
364 else if (source == delete_shortcut) {
365 workspace_tree.removeDirectoryMapping(node);
366 }
367
368 // Collapse folder
369 else if (source == collapse_folder) {
370 workspace_tree.collapsePath(selection_paths[0]);
371 }
372
373 // Expand folder
374 else if (source == expand_folder) {
375 workspace_tree.expandPath(selection_paths[0]);
376 }
377
378 // Open in external program
379 else if (source == open_externally) {
380 Gatherer.f_man.openFileInExternalApplication(node.getFile());
381 }
382 }
383 }
384}
Note: See TracBrowser for help on using the repository browser.