source: other-projects/FileTransfer-WebSocketPair/testGXTWithGreenstone/src/org/greenstone/gatherer/util/DragTreeSelectionModel.java@ 33053

Last change on this file since 33053 was 33053, checked in by ak19, 5 years ago

I still had some stuff of Nathan Kelly's (FileTransfer-WebSocketPair) sitting on my USB. Had already commited the Themes folder at the time, 2 years back. Not sure if he wanted this additional folder commited. But I didn't want to delete it and decided it will be better off on SVN. When we use his project, if we find we didn't need this test folder, we can remove it from svn then.

File size: 8.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.util;
38
39import java.awt.Point;
40import java.awt.event.*;
41import javax.swing.tree.*;
42import org.greenstone.gatherer.DebugStream;
43import org.greenstone.gatherer.Dictionary;
44import org.greenstone.gatherer.gui.tree.DragTree;
45
46public class DragTreeSelectionModel
47 extends DefaultTreeSelectionModel
48 implements MouseListener {
49
50 private boolean immediate = false;
51 private boolean mixed_selection = false;
52
53 private int type = -1;
54
55 private TreePath temp_path = null;
56 private TreePath temp_paths[] = null;
57
58 static private final int NONE = -1;
59 static private final int ADD = 0;
60 static private final int SET = 1;
61
62 /** Constructor.
63 * @param tree the DragTree which will use this selection model.
64 * @param mixed_selection true if this selection model allows selections to contain files and folders, false otherwise.
65 */
66 public DragTreeSelectionModel(DragTree tree, boolean mixed_selection) {
67 super();
68 this.mixed_selection = mixed_selection;
69 setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);
70 tree.addMouseListener(this);
71 }
72
73 public void addSelectionPath(TreePath path) {
74 if(!immediate) {
75 this.temp_path = path;
76 this.type = this.ADD;
77 }
78 else if(isAppropriate(path)) {
79 temp_path = null;
80 super.addSelectionPath(path);
81 }
82 }
83
84 public void addSelectionPaths(TreePath paths[]) {
85 if(!immediate) {
86 this.temp_paths = paths;
87 this.type = this.ADD;
88 }
89 else if(isAppropriate(paths, true)) {
90 temp_paths = null;
91 super.setSelectionPaths(paths);
92 }
93 }
94
95 public String getDetails() {
96 String suffix = null;
97 int file_count = 0;
98 int folder_count = 0;
99 for(int i = 0; selection != null && i < selection.length; i++) {
100 TreeNode node = (TreeNode) selection[i].getLastPathComponent();
101 if(node.isLeaf()) {
102 file_count++;
103 }
104 else {
105 folder_count++;
106 }
107 }
108
109 // Update the metaaudit_suffix
110 String args[] = null;
111 if(file_count > 0 && folder_count > 0) {
112 if(file_count > 1 && folder_count > 1) {
113 args = new String[2];
114 args[0] = String.valueOf(file_count);
115 args[1] = String.valueOf(folder_count);
116 suffix = Dictionary.get("FileActions.Selected", args);
117 }
118 else if(file_count > 1) {
119 args = new String[1];
120 args[0] = String.valueOf(file_count);
121 suffix = Dictionary.get("FileActions.Files_And_Directory_Selected", args);
122 }
123 else if(folder_count > 1) {
124 args = new String[1];
125 args[0] = String.valueOf(folder_count);
126 suffix = Dictionary.get("FileActions.File_And_Directories_Selected", args);
127 }
128 else {
129 suffix = Dictionary.get("FileActions.File_And_Directory_Selected");
130 }
131 }
132 else if(file_count > 0) {
133 if(file_count > 1) {
134 args = new String[1];
135 args[0] = String.valueOf(file_count);
136 suffix = Dictionary.get("FileActions.Files_Selected", args);
137 }
138 else if(file_count == 1) {
139 suffix = Dictionary.get("FileActions.File_Selected");
140 }
141 }
142 else if(folder_count > 0) {
143 if(folder_count > 1) {
144 args = new String[1];
145 args[0] = String.valueOf(folder_count);
146 suffix = Dictionary.get("FileActions.Directories_Selected", args);
147 }
148 else {
149 suffix = Dictionary.get("FileActions.Directory_Selected");
150 }
151 }
152 args = null;
153
154 return suffix;
155 }
156
157 /** Any implementation of MouseListener must include this method so
158 * we can be informed when the mouse is clicked.
159 * @param event A MouseEvent containing all the information about
160 * this mouse click.
161 */
162 public void mouseClicked(MouseEvent event) {
163 }
164
165 /** Any implementation of MouseListener must include this method so
166 * we can be informed when the mouse enters a component.
167 * @param event A MouseEvent containing all the information about
168 * this mouse action.
169 */
170 public void mouseEntered(MouseEvent event) {
171 }
172
173 /** Any implementation of MouseListener must include this method so
174 * we can be informed when the mouse exits a component.
175 * @param event A MouseEvent containing all the information about
176 * this mouse action.
177 */
178 public void mouseExited(MouseEvent event) {
179 }
180
181 /** Any implementation of MouseListener must include this method so
182 * we can be informed when the mouse is pressed (start of click).
183 * @param event A MouseEvent containing all the information about
184 * this mouse action.
185 */
186 public void mousePressed(MouseEvent event) {
187 }
188
189 /** Any implementation of MouseListener must include this method so
190 * we can be informed when the mouse is released (end of click).
191 * @param event A MouseEvent containing all the information about
192 * this mouse action.
193 */
194 public void mouseReleased(MouseEvent event) {
195 try {
196 switch(this.type) {
197 case 0: // this.ADD
198 if(this.temp_path != null && isAppropriate(temp_path)) {
199 super.addSelectionPath(this.temp_path);
200 this.temp_path = null;
201 }
202 if(this.temp_paths != null && isAppropriate(temp_paths, true)) {
203 super.addSelectionPaths(this.temp_paths);
204 this.temp_paths = null;
205 }
206 this.type = this.NONE;
207 break;
208 case 1: // this.SET
209 if(this.temp_path != null) {
210 super.setSelectionPath(this.temp_path);
211 this.temp_path = null;
212 }
213 if(this.temp_paths != null && isAppropriate(temp_paths, false)) {
214 super.setSelectionPaths(this.temp_paths);
215 this.temp_paths = null;
216 }
217 this.type = this.NONE;
218 break;
219 }
220 }
221 catch (Exception error) {
222 DebugStream.printStackTrace(error);
223 }
224 }
225
226 public void setImmediate(boolean value) {
227 immediate = value;
228 }
229
230 public void setSelectionPath(TreePath path) {
231 // Since this is only a single path we don't need to check whether its an appropriate selection.
232 if(!immediate) {
233 this.temp_path = path;
234 this.type = this.SET;
235 }
236 else {
237 temp_path = null;
238 super.setSelectionPath(path);
239 }
240 }
241
242 public void setSelectionPaths(TreePath paths[]) {
243 if(!immediate) {
244 this.temp_paths = paths;
245 this.type = this.SET;
246 }
247 else if(isAppropriate(paths, false)) {
248 temp_paths = null;
249 super.setSelectionPaths(paths);
250 }
251 }
252
253 /** Ensure that the given path is appropriate to add to the current selection, preventing mixed selections of files and folder if required. We also must check that no path is a ancestor/descendant of another.
254 */
255 private boolean isAppropriate(TreePath path) {
256 boolean appropriate = true;
257 TreeNode new_node = (TreeNode) path.getLastPathComponent();
258 // If there is a current selection
259 if(selection != null && selection.length > 0) {
260 for(int i = 0; appropriate && i < selection.length; i++) {
261 TreeNode current_node = (TreeNode) selection[i].getLastPathComponent();
262 appropriate = appropriate && (mixed_selection || new_node.isLeaf() == current_node.isLeaf());
263 appropriate = appropriate && !path.isDescendant(selection[i]) && !selection[i].isDescendant(path);
264 }
265 }
266 return appropriate;
267 }
268 /** Ensure that the given paths are appropriate to add to the current selection, preventing mixed selections of files and folder if required. We also must check that no path is a ancestor/descendant of another. One last detail to keep in mind is that adding selections depends upon the current selection, whereas set the selection paths doesn't (replaces them instead) and thus no check of the current paths is needed. */
269 private boolean isAppropriate(TreePath[] paths, boolean check_current) {
270 boolean appropriate = true;
271 if(check_current && paths != null && paths.length > 0) {
272 for(int i = 0; appropriate && i < paths.length; i++) {
273 appropriate = appropriate && isAppropriate(paths[i]);
274 }
275 }
276 return appropriate;
277 }
278}
Note: See TracBrowser for help on using the repository browser.