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

Last change on this file since 22342 was 22342, checked in by sjm84, 14 years ago

An error message is now displayed if you try to create a shortcut of a folder that does not exist

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