Changeset 4367
- Timestamp:
- 2003-05-27T15:58:15+12:00 (21 years ago)
- Location:
- trunk/gli/src/org/greenstone/gatherer/gui
- Files:
-
- 45 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/gui/AboutDialog.java
r4293 r4367 47 47 */ 48 48 public class AboutDialog 49 50 51 49 extends JDialog { 50 private AboutDialog self; 51 private JButton close_button; 52 52 53 54 53 static final private Dimension SIZE = new Dimension(600, 325); 54 static final private int ICON_SIZE = 65; 55 55 56 57 58 59 56 public AboutDialog(JFrame parent) { 57 super(parent, get("Title"), true); 58 this.self = this; 59 setSize(SIZE); 60 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 61 JPanel content_pane = (JPanel) getContentPane(); 62 JPanel upper_pane = new JPanel(); 63 ImageIcon icon = Utility.getImage("medgath.gif"); 64 ImageIcon scaled_icon = new ImageIcon(icon.getImage().getScaledInstance(ICON_SIZE, ICON_SIZE, Image.SCALE_DEFAULT)); 65 JLabel icon_label = new JLabel(scaled_icon); 66 JPanel title_pane = new JPanel(); 67 JLabel title_one_label = new JLabel(get("Title_One")); 68 JLabel title_two_label = new JLabel(Utility.PROGRAM_NAME + " " + Utility.PROGRAM_VERSION); 69 JLabel title_three_label = new JLabel(get("Title_Two")); 70 JLabel copyright_label = new JLabel(get("Copyright")); 71 JTextArea text = new JTextArea(); 72 text.setLineWrap(true); 73 text.setWrapStyleWord(true); 74 JPanel button_pane = new JPanel(); 75 close_button = new JButton(get("General.Close")); 76 76 77 78 77 // Connection 78 close_button.addActionListener(new CloseButtonListener()); 79 79 80 81 80 // Layout 81 icon_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,10)); 82 82 83 84 85 86 87 83 title_pane.setLayout(new GridLayout(4,1,0,2)); 84 title_pane.add(title_one_label); 85 title_pane.add(title_two_label); 86 title_pane.add(title_three_label); 87 title_pane.add(copyright_label); 88 88 89 90 91 92 89 upper_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); 90 upper_pane.setLayout(new BorderLayout()); 91 upper_pane.add(icon_label, BorderLayout.WEST); 92 upper_pane.add(title_pane, BorderLayout.CENTER); 93 93 94 95 96 94 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 95 button_pane.setLayout(new BorderLayout()); 96 button_pane.add(close_button, BorderLayout.EAST); 97 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 98 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 99 content_pane.setLayout(new BorderLayout()); 100 content_pane.add(upper_pane, BorderLayout.NORTH); 101 content_pane.add(new JScrollPane(text), BorderLayout.CENTER); 102 content_pane.add(button_pane, BorderLayout.SOUTH); 103 // Build text content 104 text.append(get("Java_Req")); 105 text.append("\n"); 106 text.append(get("Java_Req_One")); 107 text.append("\n"); 108 text.append(get("Java_Req_Two")); 109 text.append("\n\n"); 110 text.append("*****" + get("Acknowledgement") + "*****"); 111 text.append("\n\n"); 112 text.append(get("Item0")); 113 text.append("\n\n"); 114 text.append(get("Item1")); 115 text.append("\n\n"); 116 text.append(get("Item2")); 117 text.append("\n\n"); 118 text.append(get("Item3")); 119 text.append("\n\n"); 120 text.append("*****" + get("Thanks") + "*****"); 121 text.append("\n\n"); 122 text.append(get("Item4")); 123 text.append("\n\n"); 124 text.append(get("Item5")); 125 text.append("\n\n"); 126 text.append(get("Item6")); 127 text.append("\n\n"); 128 text.append(get("Item7")); 129 text.setCaretPosition(0); 130 130 131 132 133 134 135 131 // Show 132 Rectangle frame_bounds = parent.getBounds(); 133 setLocation(frame_bounds.x + (frame_bounds.width - SIZE.width) / 2, frame_bounds.y + (frame_bounds.height - SIZE.height) / 2); 134 show(); 135 } 136 136 137 138 139 140 141 142 143 137 private class CloseButtonListener 138 implements ActionListener { 139 public void actionPerformed(ActionEvent event) { 140 self.hide(); 141 self.dispose(); 142 } 143 } 144 144 145 146 147 148 149 150 145 static private String get(String key) { 146 if(key.indexOf(".") == -1) { 147 key = "AboutDialog." + key; 148 } 149 return Gatherer.dictionary.get(key); 150 } 151 151 } -
trunk/gli/src/org/greenstone/gatherer/gui/BorderFactory.java
r4293 r4367 10 10 */ 11 11 public class BorderFactory { 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 12 /** Creates a beveled border of the specified type, using brighter shades of the component's current background color for highlighting, and darker shading for shadows. */ 13 static public Border createBevelBorder(int type) { 14 return javax.swing.BorderFactory.createBevelBorder(type); 15 } 16 /** Creates a beveled border of the specified type, using the specified highlighting and shadowing. */ 17 static public Border createBevelBorder(int type, Color highlight, Color shadow) { 18 return javax.swing.BorderFactory.createBevelBorder(type, highlight, shadow); 19 } 20 /** Creates a beveled border of the specified type, using the specified colors for the inner and outer highlight and shadow areas. */ 21 static public Border createBevelBorder(int type, Color highlightOuter, Color highlightInner, Color shadowOuter, Color shadowInner) { 22 return javax.swing.BorderFactory.createBevelBorder(type, highlightOuter, highlightInner, shadowOuter, shadowInner); 23 } 24 /** Creates a compound border with a null inside edge and a null outside edge. */ 25 static public CompoundBorder createCompoundBorder() { 26 return javax.swing.BorderFactory.createCompoundBorder(); 27 } 28 /** Creates a compound border specifying the border objects to use for the outside and inside edges. */ 29 static public CompoundBorder createCompoundBorder(Border outsideBorder, Border insideBorder) { 30 return javax.swing.BorderFactory.createCompoundBorder(outsideBorder, insideBorder); 31 } 32 /** Creates an empty border that takes up no space. */ 33 static public Border createEmptyBorder() { 34 return javax.swing.BorderFactory.createEmptyBorder(); 35 } 36 /** Creates an empty border that takes up space but which does no drawing, specifying the width of the top, left, bottom, and right sides. */ 37 static public Border createEmptyBorder(int top, int left, int bottom, int right) { 38 return javax.swing.BorderFactory.createEmptyBorder(top, left, bottom, right); 39 } 40 /** Creates a border with an "etched" look using the component's current background color for highlighting and shading. */ 41 static public Border createEtchedBorder() { 42 return javax.swing.BorderFactory.createEtchedBorder(); 43 } 44 /** Creates a border with an "etched" look using the specified highlighting and shading colors. */ 45 static public Border createEtchedBorder(Color highlight, Color shadow) { 46 return javax.swing.BorderFactory.createEtchedBorder(highlight, shadow); 47 } 48 /** Creates a border with an "etched" look using the component's current background color for highlighting and shading. */ 49 static public Border createEtchedBorder(int type) { 50 return javax.swing.BorderFactory.createEtchedBorder(type); 51 } 52 /** Creates a border with an "etched" look using the specified highlighting and shading colors. */ 53 static public Border createEtchedBorder(int type, Color highlight, Color shadow) { 54 return javax.swing.BorderFactory.createEtchedBorder(type, highlight, shadow); 55 } 56 /** Creates a line border withe the specified color. */ 57 static public Border createLineBorder(Color color) { 58 return javax.swing.BorderFactory.createLineBorder(color); 59 } 60 /** Creates a line border with the specified color and width. */ 61 static public Border createLineBorder(Color color, int thickness) { 62 return javax.swing.BorderFactory.createLineBorder(color, thickness); 63 } 64 /** Creates a border with a lowered beveled edge, using brighter shades of the component's current background color for highlighting, and darker shading for shadows. */ 65 static public Border createLoweredBevelBorder() { 66 return javax.swing.BorderFactory.createLoweredBevelBorder(); 67 } 68 /** Creates a matte-look border using a solid color. */ 69 static public MatteBorder createMatteBorder(int top, int left, int bottom, int right, Color color) { 70 return javax.swing.BorderFactory.createMatteBorder(top, left, bottom, right, color); 71 } 72 /** Creates a matte-look border that consists of multiple tiles of a specified icon. */ 73 static public MatteBorder createMatteBorder(int top, int left, int bottom, int right, Icon tileIcon) { 74 return javax.swing.BorderFactory.createMatteBorder(top, left, bottom, right, tileIcon); 75 } 76 /** Creates a border with a raised beveled edge, using brighter shades of the component's current background color for highlighting, and darker shading for shadows. */ 77 static public Border createRaisedBevelBorder() { 78 return javax.swing.BorderFactory.createRaisedBevelBorder(); 79 } 80 /** Creates a new title border with an empty title specifying the border object, using the default text position (sitting on the top line) and default justification (leading) and using the default font, and text color. */ 81 static public org.greenstone.gatherer.gui.border.TitledBorder createTitledBorder(Border border) { 82 return new org.greenstone.gatherer.gui.border.TitledBorder(border); 83 } 84 /** Adds a title to an existing border, specifying the text of the title, using the default positioning (sitting on the top line) and default justification (leading) and using the default font and text color determined by the current look and feel. */ 85 static public org.greenstone.gatherer.gui.border.TitledBorder createTitledBorder(Border border, String title) { 86 return new org.greenstone.gatherer.gui.border.TitledBorder(border, title); 87 } 88 /** Adds a title to an existing border, specifying the text of the title along with its positioning, using the default font and text color determined by the current look and feel. */ 89 static public org.greenstone.gatherer.gui.border.TitledBorder createTitledBorder(Border border, String title, int justification, int position) { 90 return new org.greenstone.gatherer.gui.border.TitledBorder(border, title, justification, position); 91 } 92 /** Adds a title to an existing border, specifying the text of the title along with its positioning and font, using the default text color determined by the current look and feel. */ 93 static public org.greenstone.gatherer.gui.border.TitledBorder createTitledBorder(Border border, String title, int justification, int position, Font font) { 94 return new org.greenstone.gatherer.gui.border.TitledBorder(border, title, justification, position, font); 95 } 96 /** Adds a title to an existing border, specifying the text of the title along with its positioning, font, and color. */ 97 static public org.greenstone.gatherer.gui.border.TitledBorder createTitledBorder(Border border, String title, int justification, int position, Font font, Color color) { 98 return new org.greenstone.gatherer.gui.border.TitledBorder(border, title, justification, position, font, color); 99 } 100 /** Creates a new title border specifying the text of the title, using the default border (etched), using the default text position (sitting on the top line) and default justification (leading) and using the default font and text color determined by the current look and feel. */ 101 static public org.greenstone.gatherer.gui.border.TitledBorder createTitledBorder(String title) { 102 return new org.greenstone.gatherer.gui.border.TitledBorder(title); 103 } 104 104 } -
trunk/gli/src/org/greenstone/gatherer/gui/BrowsingPane.java
r4293 r4367 50 50 */ 51 51 public class BrowsingPane 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 /** Called to validate the status of the controls. Disables those that are no longer applicable or restores those that have come back into scope of usage.194 195 196 197 198 199 200 201 202 203 52 extends JPanel { 53 private Bookmarks bookmarks = null; 54 private CalHTMLPane view_pane = null; 55 private CalHTMLPreferences preferences = null; 56 private int back_count = 0; 57 private int forward_count = 0; 58 private JButton back_button = null; 59 private JButton bookmarks_button = null; // Collection bookmarks. 60 private JButton forward_button = null; 61 private JButton go_button = null; 62 private JButton home_button = null; 63 private JButton refresh_button = null; 64 private JButton reload_button = null; 65 private JButton stop_button = null; 66 private JLabel status_label = null; 67 private JTextField address_field = null; 68 private Observer observer = null; 69 private String args[] = null; 70 static final String BOOKMARKS_FILE = "bookmarks.txt"; 71 public BrowsingPane() { 72 super(); 73 // Initialization 74 bookmarks = new Bookmarks(); // Empty until collection loaded. 75 observer = new Observer(); 76 preferences = new CalHTMLPreferences(); 77 preferences.setHomeURL((new GURL(Gatherer.config.getString("general.home_page", false))).getURL()); 78 // Creation 79 // Controls 80 JPanel button_pane = new JPanel(); 81 JPanel left_button_pane = new JPanel(); 82 back_button = new JButton("", Utility.getImage("back.gif")); 83 back_button.setEnabled(false); 84 back_button.setToolTipText(get("Back")); 85 refresh_button = new JButton("", Utility.getImage("reload.gif")); 86 refresh_button.setEnabled(false); 87 refresh_button.setToolTipText(get("Reload")); 88 bookmarks_button = new JButton("", Utility.getImage("bookmark.gif")); 89 bookmarks_button.setToolTipText(get("Bookmarks")); 90 home_button = new JButton("", Utility.getImage("home.gif")); 91 home_button.setToolTipText(get("Home")); 92 JPanel address_pane = new JPanel(); 93 address_field = new JTextField(Gatherer.config.getString("general.home_page", false)); 94 JPanel right_button_pane = new JPanel(); 95 go_button = new JButton("", Utility.getImage("go.gif")); 96 go_button.setToolTipText(get("Go")); 97 stop_button = new JButton("", Utility.getImage("stop.gif")); 98 stop_button.setEnabled(false); 99 stop_button.setToolTipText(get("Stop")); 100 forward_button = new JButton("", Utility.getImage("forward.gif")); 101 forward_button.setEnabled(false); 102 forward_button.setToolTipText(get("Forward")); 103 // Calpa Pane stuff 104 view_pane = new CalHTMLPane(preferences, observer, "VIEW_PANE"); 105 // Status bar 106 status_label = new JLabel(get("Ready")); 107 // Connection 108 address_field.addActionListener(new AddressFieldListener()); 109 back_button.addActionListener(new BackButtonListener()); 110 bookmarks_button.addActionListener(new BookMarksButtonListener()); 111 forward_button.addActionListener(new ForwardButtonListener()); 112 go_button.addActionListener(new GoButtonListener()); 113 home_button.addActionListener(new HomeButtonListener()); 114 refresh_button.addActionListener(new RefreshButtonListener()); 115 stop_button.addActionListener(new StopButtonListener()); 116 // Layout 117 left_button_pane.setLayout(new GridLayout(1,3)); 118 left_button_pane.add(back_button); 119 left_button_pane.add(bookmarks_button); 120 left_button_pane.add(home_button); 121 122 address_pane.setBorder(BorderFactory.createEmptyBorder(10,5,10,5)); 123 address_pane.setLayout(new BorderLayout()); 124 address_pane.add(address_field, BorderLayout.CENTER); 125 126 right_button_pane.setLayout(new GridLayout(1,3)); 127 right_button_pane.add(go_button); 128 right_button_pane.add(stop_button); 129 right_button_pane.add(forward_button); 130 131 button_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 132 button_pane.setLayout(new BorderLayout()); 133 button_pane.add(left_button_pane, BorderLayout.WEST); 134 button_pane.add(address_pane, BorderLayout.CENTER); 135 button_pane.add(right_button_pane, BorderLayout.EAST); 136 137 setLayout(new BorderLayout()); 138 add(button_pane, BorderLayout.NORTH); 139 add(new JScrollPane(view_pane), BorderLayout.CENTER); 140 add(status_label, BorderLayout.SOUTH); 141 } 142 /** Some actions, such as getting the HTML to render properly without throwing sixty bazillion NPE's, can only occur after the frame has been drawn to screen. To this end we have this method so we can action things -after- the frame draw. 143 */ 144 public void afterDisplay() { 145 view_pane.goHome(); 146 } 147 148 /** Called when a significant change occurs to the currently loaded collection. 149 * @param ready <i>true</i> if there is a collection ready to be accessed. 150 */ 151 public void collectionChanged(boolean ready) { 152 // Reload the bookmarks associated with this collection. 153 if(ready) { 154 bookmarks.load(); 155 } 156 else { 157 bookmarks.clear(); 158 } 159 } 160 161 /** If some external class has possibly changed the state of the browsing pane then the controls should be repolled to determine which are still valid. 162 */ 163 public void controlsChanged() { 164 } 165 166 /** Retrieves the current address entered in the address Textfield. 167 * @return A <strong>String</strong> representing the currently entered address. 168 */ 169 public String getCurrentURL() { 170 return address_field.getText(); 171 } 172 173 174 /** Retrieves a key from the Dictionary, using no extra arguments. 175 * @param key A <strong>String</strong> which maps to a certain phrase from the Dictionary. 176 * @return The <strong>String</strong> that matches the key or an error message if no match was found. 177 */ 178 private String get(String key) { 179 return get(key, null); 180 } 181 182 /** Retrieves a key from the Dictionary, providing extra arguments to be inserted using a String array. 183 * @param key A <strong>String</strong> which maps to a certain phrase from the Dictionary. 184 * @param args A <strong>String[]</strong> containing further arguments (such as formatting instructions and variable values) to be taken into account when Dictionary creates the return String. 185 * @return The <strong>String</strong> that matches the key or an error message if no match was found. 186 */ 187 private String get(String key, String args[]) { 188 if(key.indexOf('.') == -1) { 189 key = "Browser." + key; 190 } 191 return Gatherer.dictionary.get(key,args); 192 } 193 /** Called to validate the status of the controls. Disables those that are no longer applicable or restores those that have come back into scope of usage. 194 * @param update_address <i>true</i> if this pollControls call should update the address bar, <i>false</i> otherwise. 195 */ 196 private void validateControls() { 197 back_button.setEnabled(back_count > 0); 198 forward_button.setEnabled(forward_count > 0); 199 } 200 201 private class AddressFieldListener 202 implements ActionListener { 203 public void actionPerformed(ActionEvent event) { 204 204 // Attempt to create a GURL 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 205 GURL url = new GURL(address_field.getText()); 206 address_field.setText(url.getURL().toString()); 207 if(url.valid()) { 208 // Now load document 209 view_pane.showHTMLDocument(url.getURL()); 210 back_count++; 211 forward_count = 0; 212 } 213 validateControls(); 214 } 215 } 216 217 private class BackButtonListener 218 implements ActionListener { 219 public void actionPerformed(ActionEvent event) { 220 view_pane.goBack(); 221 back_count--; 222 forward_count++; 223 validateControls(); 224 } 225 } 226 227 private class Bookmarks 228 extends JDialog { 229 230 private DefaultListModel data = null; 231 232 public Bookmarks() { 233 data = new DefaultListModel(); 234 } 235 236 public void clear() { 237 data.removeAllElements(); 238 238 // Re-add the "Add Bookmark" entry. 239 239 //add 240 241 242 240 } 241 242 public void load() { 243 243 // Clear existing 244 244 data.removeAllElements(); 245 245 // Determine the file to load from... 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 246 File bookmarks = new File(Gatherer.c_man.getCollectionDirectory() + BOOKMARKS_FILE); 247 if(bookmarks.exists()) { 248 // Read in file line at a time adding to bookmarks. 249 } 250 } 251 252 public int count() { 253 return data.size(); 254 } 255 256 private class Entry { 257 public String title = null; 258 public URL url = null; 259 public Entry(String title, String url_raw) { 260 this.title = title; 261 try { 262 url = new URL(url_raw); 263 } 264 catch(Exception error) { 265 266 } 267 } 268 public String toString() { 269 return title; 270 } 271 } 272 } 273 274 private class BookMarksButtonListener 275 implements ActionListener { 276 public void actionPerformed(ActionEvent event) { 277 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 278 } 279 } 280 281 private class ForwardButtonListener 282 implements ActionListener { 283 public void actionPerformed(ActionEvent event) { 284 view_pane.goForward(); 285 back_count++; 286 forward_count--; 287 validateControls(); 288 } 289 } 290 291 private class GoButtonListener 292 implements ActionListener { 293 public void actionPerformed(ActionEvent event) { 294 294 // Attempt to create a GURL 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 295 GURL url = new GURL(address_field.getText()); 296 address_field.setText(url.getURL().toString()); 297 if(url.valid()) { 298 // Now load document 299 view_pane.showHTMLDocument(url.getURL()); 300 back_count++; 301 forward_count = 0; 302 } 303 validateControls(); 304 } 305 } 306 307 private class HomeButtonListener 308 implements ActionListener { 309 public void actionPerformed(ActionEvent event) { 310 address_field.setText(Gatherer.config.getString("general.home_page", false)); 311 view_pane.goHome(); 312 back_count++; 313 forward_count = 0; 314 validateControls(); 315 } 316 } 317 318 private class RefreshButtonListener 319 implements ActionListener { 320 public void actionPerformed(ActionEvent event) { 321 view_pane.reloadDocument(); 322 validateControls(); 323 } 324 } 325 326 private class StopButtonListener 327 implements ActionListener { 328 public void actionPerformed(ActionEvent event) { 329 view_pane.stopAll(); 330 validateControls(); 331 } 332 } 333 334 private class Observer 335 extends DefaultCalHTMLObserver { 336 public void linkActivatedUpdate(CalHTMLPane pane, URL url, String target_frame, String j_name) { 337 address_field.setText(url.toString()); 338 back_count++; 339 validateControls(); 340 } 341 public void linkFocusUpdate(CalHTMLPane pane, URL url) { 342 342 ///ystem.err.println("Link in focus " + url.toString()); 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 343 args = new String[1]; 344 args[0] = url.toString(); 345 status_label.setText(get("Follow")); 346 args = null; 347 } 348 public void statusUpdate(CalHTMLPane pane, int state, URL url, int value, String message) { 349 switch(state) { 350 case 11: 351 // Can only stop if somethings happening. 352 stop_button.setEnabled(true); 353 args = new String[1]; 354 args[0] = url.toString(); 355 status_label.setText(get("Loading", args)); 356 args = null; 357 break; 358 case 14: 359 // All done. 360 stop_button.setEnabled(false); 361 // Rendering complete. 362 status_label.setText(get("Ready")); 363 go_button.setEnabled(true); 364 stop_button.setEnabled(false); 365 refresh_button.setEnabled(true); 366 // Update mirror pane 367 Gatherer.g_man.mirror_pane.setURL(url.toString()); 368 break; 369 case 74: 370 address_field.setText(url.toString()); 371 default: 372 ///ystem.err.println(state + ": " + url + " \"" + message + "\""); 373 } 374 } 375 } 376 376 } -
trunk/gli/src/org/greenstone/gatherer/gui/BuildOptions.java
r4293 r4367 46 46 */ 47 47 public class BuildOptions 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 48 implements Serializable { 49 /** Do we include empty classifications? */ 50 public boolean allclassifications = false; 51 /** Have we set an archive directory? */ 52 public boolean archivedir = false; 53 /** Have we set a build directory? */ 54 public boolean builddir = false; 55 /** Do we want debug information? */ 56 public boolean debug = false; 57 /** Have we set a collect directory? */ 58 public boolean collectdir = false; 59 /** Do we want the build process to create images as it goes along? */ 60 public boolean create_images = false; 61 /** Have we set a groupsize value? */ 62 public boolean groupsize = false; 63 /** Do we want the contents of the archive directory zipped? */ 64 public boolean gzip = false; 65 /** Have we set an import directory? */ 66 public boolean importdir = false; 67 /** Have we selected to build the collection on certain indexes? */ 68 public boolean index = false; 69 /** Do we explicitly want to keep the archives dir? */ 70 public boolean keepold = false; 71 /** Have we set a maxdocs value? */ 72 public boolean maxdocs = false; 73 /** Have we selected a certain mode to build in? */ 74 public boolean mode = false; 75 /** Do we build the indexes, but store no compressed text? */ 76 public boolean notext = false; 77 /** Have we decided on a OID type? */ 78 public boolean oidtype = false; 79 /** Have we set an out file? */ 80 public boolean out = false; 81 /** Do we explicitly want to remove the archives dir? */ 82 public boolean removeold = false; 83 /** Have we choosen a metadata element to sort on? */ 84 public boolean sortmeta = false; 85 /** Have we set a verbosity value? */ 86 public boolean verbosity = false; 87 /** How many documents to a hash group in the archive? */ 88 public int groupsize_value = 1; 89 /** What is the maximum number of documents to process? */ 90 public int maxdocs_value = 1; 91 /** What is the desired level of verbosity? */ 92 public byte verbosity_value = 0; 93 /** The archive directory. */ 94 public String archivedir_value = ""; 95 /** The building directory. */ 96 public String builddir_value = ""; 97 /** The collect directory. */ 98 public String collectdir_value = ""; 99 /** The import directory. */ 100 public String importdir_value = ""; 101 /** The build mode. */ 102 public String mode_value = ""; 103 /** The OID generation method. */ 104 public String oidtype_value = ""; 105 /** The name of the file to write std_err to. */ 106 public String out_value = ""; 107 /** The name of the metadata element to sort the collection by. */ 108 public String sortmeta_value = ""; 109 /** The names of classifiers to be indexes for. */ 110 public String[] index_value = null; 111 /** Element of argument type enumeration. */ 112 static final public byte BUILD_ARGS = 0; 113 /** Element of argument type enumeration. */ 114 static final public byte IMPORT_ARGS = 1; 115 /** Element of option type enumeration. */ 116 static final public byte ALLCLASSIFICATIONS = 0; 117 /** Element of option type enumeration. */ 118 static final public byte ARCHIVEDIR = 1; 119 /** Element of option type enumeration. */ 120 static final public byte BUILDDIR = 2; 121 /** Element of option type enumeration. */ 122 static final public byte DEBUG = 3; 123 /** Element of option type enumeration. */ 124 static final public byte COLLECTDIR = 4; 125 /** Element of option type enumeration. */ 126 static final public byte CREATEIMAGES = 5; 127 /** Element of option type enumeration. */ 128 static final public byte GROUPSIZE = 6; 129 /** Element of option type enumeration. */ 130 static final public byte GZIP = 7; 131 /** Element of option type enumeration. */ 132 static final public byte IMPORTDIR = 8; 133 /** Element of option type enumeration. */ 134 static final public byte INDEX = 9; 135 /** Element of option type enumeration. */ 136 static final public byte KEEPOLD = 10; 137 /** Element of option type enumeration. */ 138 static final public byte MAXDOCS = 11; 139 /** Element of option type enumeration. */ 140 static final public byte MODE = 12; 141 /** Element of option type enumeration. */ 142 static final public byte NOTEXT = 13; 143 /** Element of option type enumeration. */ 144 static final public byte OIDTYPE = 14; 145 /** Element of option type enumeration. */ 146 static final public byte OUT = 15; 147 /** Element of option type enumeration. */ 148 static final public byte REMOVEOLD = 16; 149 /** Element of option type enumeration. */ 150 static final public byte SORTMETA = 17; 151 /** Element of option type enumeration. */ 152 static final public byte VERBOSITY = 18; 153 /** This constructor initializes values by using the current configuration and collect if there is one. 154 */ 155 public BuildOptions() { 156 collectdir_value = Utility.getCollectionDir(Gatherer.config.gsdl_path); 157 // If we have a collection open gets its details. 158 if(Gatherer.c_man.ready()) { 159 archivedir_value = Gatherer.c_man.getCollectionArchive(); 160 builddir_value = Gatherer.c_man.getCollectionBuild(); 161 importdir_value = Gatherer.c_man.getCollectionImport(); 162 } 163 } 164 /** This method returns a copy of this current <strong>BuildOptions</strong> object. Tried using stupid <i>Clonable</i> interface but it didn't work. 165 165 * @return A <strong>BuildOptions</strong> object with the same settings as this one. 166 166 */ 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 167 public BuildOptions copy() { 168 BuildOptions options = new BuildOptions(); 169 options.allclassifications = allclassifications; 170 options.archivedir = archivedir; 171 options.builddir = builddir; 172 options.debug = debug; 173 options.collectdir = collectdir; 174 options.create_images = create_images; 175 options.groupsize = groupsize; 176 options.gzip = gzip; 177 options.importdir = importdir; 178 options.index = index; 179 options.keepold = keepold; 180 options.maxdocs = maxdocs; 181 options.mode = mode; 182 options.notext = notext; 183 options.oidtype = oidtype; 184 options.out = out; 185 options.removeold = removeold; 186 options.sortmeta = sortmeta; 187 options.verbosity = verbosity; 188 options.groupsize_value = groupsize_value; 189 options.maxdocs_value = maxdocs_value; 190 options.verbosity_value = verbosity_value; 191 options.archivedir_value = archivedir_value; 192 options.builddir_value = builddir_value; 193 options.collectdir_value = collectdir_value; 194 options.importdir_value = importdir_value; 195 options.mode_value = mode_value; 196 options.oidtype_value = oidtype_value; 197 options.out_value = out_value; 198 options.sortmeta_value = sortmeta_value; 199 options.index_value = index_value; 200 return options; 201 } 202 /** When called this method returns the required arguments selected by the user. Only those arguments that are selected are returned, and even then some are never returned (i.e -out which is handled within the GShells instead). 203 203 * @param type The type of process that will recieve these arguments as a <strong>byte</strong>. 204 204 * @return A <strong>String[]</strong> containing the arguments and any required parameters as set by the user. 205 205 */ 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 206 public String[] getArguments(byte type) { 207 ArrayList arguments = new ArrayList(); 208 if(allclassifications && type == BUILD_ARGS) { 209 arguments.add("-allclassifications"); 210 } 211 if(archivedir) { 212 arguments.add("-archivedir"); 213 arguments.add(archivedir_value); 214 } 215 if(builddir && type == BUILD_ARGS) { 216 arguments.add("-builddir"); 217 arguments.add(builddir_value); 218 } 219 if(debug) { 220 arguments.add("-debug"); 221 } 222 if(collectdir) { 223 arguments.add("-collectdir"); 224 arguments.add(collectdir_value); 225 } 226 if(create_images && type == BUILD_ARGS) { 227 arguments.add("-create_images"); 228 } 229 if(groupsize && type == IMPORT_ARGS) { 230 arguments.add("-groupsize"); 231 arguments.add(String.valueOf(groupsize_value)); 232 } 233 if(gzip && type == IMPORT_ARGS) { 234 arguments.add("-gzip"); 235 } 236 // Always ignore importdir eh? 237 if(false && importdir && type == IMPORT_ARGS) { 238 arguments.add("-importdir"); 239 arguments.add(importdir_value); 240 } 241 if(index && type == BUILD_ARGS) { 242 arguments.add("-index"); 243 StringBuffer temp = new StringBuffer(""); 244 for(int i = 0; i < index_value.length; i++) { 245 temp.append(index_value[i]); 246 temp.append(","); 247 } 248 248 // Remember to remove extra ',' 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 249 arguments.add(temp.substring(0, temp.length() - 1)); 250 } 251 if(keepold) { 252 arguments.add("-keepold"); 253 } 254 if(maxdocs) { 255 arguments.add("-maxdocs"); 256 arguments.add(String.valueOf(maxdocs_value)); 257 } 258 if(mode && type == BUILD_ARGS) { 259 arguments.add("-mode"); 260 arguments.add(mode_value); 261 } 262 if(notext && type == BUILD_ARGS) { 263 arguments.add("-no_text"); 264 } 265 if(oidtype && type == IMPORT_ARGS) { 266 arguments.add("-OIDtype"); 267 arguments.add(oidtype_value); 268 } 269 // Never do out as its handled by the GShell. 270 if(removeold && type == IMPORT_ARGS) { 271 arguments.add("-removeold"); 272 } 273 if(sortmeta && type == IMPORT_ARGS) { 274 arguments.add("-sortmeta"); 275 arguments.add(sortmeta_value); 276 } 277 if(verbosity) { 278 arguments.add("-verbosity"); 279 arguments.add(String.valueOf(verbosity_value)); 280 } 281 return ArrayTools.arrayListToStringArray(arguments); 282 } 283 283 } -
trunk/gli/src/org/greenstone/gatherer/gui/CollectionPane.java
r4305 r4367 62 62 */ 63 63 public class CollectionPane 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 64 extends JPanel 65 implements ActionListener, FocusListener { 66 /** 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. */ 67 private DragGroup group = null; 68 /** The tree showing the files within the collection. */ 69 private DragTree collection_tree = null; 70 /** The tree showing the available source workspace. */ 71 private DragTree workspace_tree = null; 72 /** The threaded queue that handles the actually movement of files, so that the gui remains responsive. */ 73 private FileQueue file_queue = null; 74 /** The filter currently applied to the collection tree. */ 75 private Filter collection_filter = null; 76 /** The filter currently applied to the workspace tree. */ 77 private Filter workspace_filter = null; 78 /** The collection model which is used to build, and hold the data of, the collection tree. */ 79 private TreeModel collection = null; 80 /** The GTree model used as the data source for the workspace tree. */ 81 private TreeModel workspace = null; 82 /** The button used to cancel all pending file queue jobs. */ 83 private JButton cancel_action = null; 84 /** The button used to create a new folder in the collection tree. */ 85 private JButton new_folder = null; 86 /** The label shown at the top of the collection tree. */ 87 private JLabel collection_label = null; 88 /** The label shown in the status area explaining the file apon which action is taking place. */ 89 private JLabel filename_label = null; 90 /** The label shown explaining the current state of the file queue thread. */ 91 private JLabel status_label = null; 92 /** The label at the top of the workspace tree. */ 93 private JLabel workspace_label = null; 94 /** The panel that contains the collection tree. */ 95 private JPanel collection_pane = null; 96 /** The panel that contains the various controls including the status area. */ 97 private JPanel control_pane = null; 98 /** The panel that contains the workspace tree. */ 99 private JPanel workspace_pane = null; 100 /** The scrollable area into which the collection tree is placed. */ 101 private JScrollPane collection_scroll = null; 102 /** The scrollable area into which the workspace tree is placed. */ 103 private JScrollPane workspace_scroll = null; 104 /** A split pane seperating the two trees, allowing for the screen real-estate for each to be changed. */ 105 private JSplitPane tree_pane = null; 106 /** Text fragment arguments used to fill in phrases returned from the dictionary. */ 107 private String args[] = null; 108 /** Ensures that expansion and selection events between collection trees based on the same model are synchronized. */ 109 private TreeSynchronizer collection_tree_sync = null; 110 /** Ensures that expansion and selection events between workspace trees based on the same model are synchronized. */ 111 private TreeSynchronizer workspace_tree_sync = null; 112 /** The button used to delete files, which also doubles as a drop target for files from the Trees. */ 113 private UndoManager bin_button = null; 114 /** The default size of a label in the interface. */ 115 static final private Dimension LABEL_SIZE = new Dimension(100,30); 116 /** The default size of a special mapping dialog. */ 117 static final Dimension DIALOG_SIZE = new Dimension(400, 120); 118 /** The minimum size a gui component can become. */ 119 static private Dimension MIN_SIZE = new Dimension( 90, 90); 120 /** The default size of the status area. */ 121 static private Dimension STATUS_SIZE = new Dimension(450, 120); 122 /** The initial size of the trees. */ 123 static private Dimension TREE_SIZE = new Dimension(400, 430); 124 /* Constructor. 125 * @param tree_sync Ensures that expansion events between like trees are synchronized. 126 * @see org.greenstone.gatherer.file.FileManager 127 * @see org.greenstone.gatherer.file.FileQueue 128 */ 129 public CollectionPane(TreeSynchronizer workspace_tree_sync, TreeSynchronizer collection_tree_sync) { 130 this.group = new DragGroup(); 131 this.file_queue = Gatherer.f_man.getQueue(); 132 this.collection_tree_sync = collection_tree_sync; 133 this.workspace_tree_sync = workspace_tree_sync; 134 135 // Create components. 136 cancel_action = new JButton(Utility.getImage("big_stop.gif")); 137 cancel_action.addActionListener(this); 138 cancel_action.setEnabled(false); 139 cancel_action.setMinimumSize(MIN_SIZE); 140 cancel_action.setPreferredSize(MIN_SIZE); 141 142 new_folder = new JButton(Utility.getImage("folder.gif")); 143 new_folder.addActionListener(this); 144 new_folder.setEnabled(false); 145 new_folder.setMinimumSize(MIN_SIZE); 146 new_folder.setPreferredSize(MIN_SIZE); 147 } 148 /** 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. */ 149 public void actionPerformed(ActionEvent event) { 150 // If a user has clicked on the bin button directly remove whatever 151 // files are selected in the active tree. 152 if(event.getSource() == bin_button) { 153 if(!bin_button.ignore()) { 154 // Find the active tree (you've made selections in). 155 DragTree tree = (DragTree) group.getActive(); 156 // Fudge things a bit 157 group.setSource(tree); 158 // Determine the selection. 159 TreePath paths[] = tree.getSelectionPaths(); 160 if(paths != null) { 161 FileNode[] source_nodes = new FileNode[paths.length]; 162 for(int i = 0; i < paths.length; i++) { 163 source_nodes[i] = (FileNode)(paths[i].getLastPathComponent()); 164 } 165 Gatherer.f_man.action(tree, source_nodes, bin_button, null); 166 } 167 } 168 } 169 // If a user has clicked on new_folder create a new folder under 170 // whatever node is selected. 171 else if(event.getSource() == new_folder && collection_tree != null) { 172 int count = collection_tree.getSelectionCount(); 173 boolean error = false; 174 if(count == 1) { 175 TreePath path = collection_tree.getSelectionPath(); 176 FileNode node = (FileNode) path.getLastPathComponent(); 177 if(node.getAllowsChildren()) { 178 Gatherer.f_man.newFolder(collection_tree, node); 179 } 180 else { 181 error = true; 182 } 183 } 184 else { 185 error = true; 186 } 187 if(error) { 188 JOptionPane.showMessageDialog(Gatherer.g_man, Gatherer.dictionary.get("FileActions.No_Parent_For_New_Folder"), Gatherer.dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE); 189 } 190 } 191 else if(event.getSource() == cancel_action) { 192 file_queue.cancelAction(); 193 } 194 } 195 /** Called whenever a significant change occurs in the current collections state, such as a new collection being loaded or the current one being closed. Several actions must occur in the GUI to indicate this change to the user, such as en/disabling the collection tree. 196 196 * @param ready <i>true</i> if a collection is loaded and ready to be modified, <i>false</i> otherwise. 197 197 * @see org.greenstone.gatherer.Configuration … … 202 202 * @see org.greenstone.gatherer.util.TreeSynchronizer 203 203 */ 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 204 public void collectionChanged(boolean ready) { 205 // Try to retrieve the collections record set. 206 collection = Gatherer.c_man.getRecordSet(); 207 if(collection != null) { 208 args = new String[1]; 209 args[0] = Gatherer.c_man.getCollection().getName(); 210 collection_label.setText(get("Collection", args)); 211 collection_tree.setModel(collection); 212 collection_tree.repaint(); 213 collection_filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false)); 214 } 215 else { 216 String args[] = new String[1]; 217 args[0] = get("Collection.No_Collection"); 218 collection_label.setText(get("Collection", args)); 219 args = null; 220 collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error"))); 221 collection_filter.setBackground(Color.lightGray); 222 } 223 223 224 225 226 227 228 229 230 231 232 233 234 224 collection_tree.setEnabled(ready); 225 collection_filter.setEnabled(ready); 226 227 // Change the label at the top of collection tree. 228 setEnabled(collection_label, ready, Gatherer.config.getColor("coloring.collection_heading_foreground", false), Gatherer.config.getColor("coloring.collection_heading_background", false)); 229 // Ensure that this tree view of the collection record set is synchronized with any others. 230 collection_tree_sync.add(collection_tree); 231 232 workspace = Gatherer.c_man.getWorkspace(); 233 workspace_tree.setModel(workspace); 234 workspace_tree_sync.add(workspace_tree); 235 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 236 // Enable or disable the control buttons 237 bin_button.setEnabled(ready); 238 cancel_action.setEnabled(ready); 239 new_folder.setEnabled(ready); 240 } 241 /** Generates the pane on controls used to 'collect' files into the collection. Resposible for creating, connecting and laying out these controls. */ 242 public void display() { 243 // Create Components. 244 KeyListenerImpl key_listener = new KeyListenerImpl(); 245 MouseListenerImpl mouse_listener = new MouseListenerImpl(); 246 this.addKeyListener(key_listener); 247 248 // Workspace Tree 249 workspace_pane = new JPanel(); 250 workspace_pane.setMinimumSize(MIN_SIZE); 251 workspace_pane.setPreferredSize(TREE_SIZE); 252 workspace_pane.setSize(TREE_SIZE); 253 254 workspace_label = new JLabel(get("Workspace")); 255 workspace_label.setOpaque(true); 256 workspace_label.setBackground(Gatherer.config.getColor("coloring.workspace_heading_background", false)); 257 workspace_label.setForeground(Gatherer.config.getColor("coloring.workspace_heading_foreground", false)); 258 259 workspace = Gatherer.c_man.getWorkspace(); 260 workspace_tree = new DragTree(Utility.WORKSPACE_TREE, workspace, null); 261 group.add(workspace_tree); 262 workspace_tree.addFocusListener(this); 263 workspace_tree.addKeyListener(key_listener); 264 workspace_tree.addMouseListener(mouse_listener); 265 workspace_tree.addMouseListener(Gatherer.g_man.foa_listener); 266 workspace_tree.addTreeExpansionListener(Gatherer.g_man.foa_listener); 267 workspace_tree.addTreeSelectionListener(file_queue); 268 workspace_tree.putClientProperty("JTree.lineStyle", "Angled"); 269 workspace_tree.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_background", false)); 270 workspace_tree.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 271 workspace_tree.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_background", false)); 272 workspace_tree.setTextSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_foreground", false)); 273 workspace_tree.setRootVisible(false); 274 275 workspace_scroll = new JScrollPane(workspace_tree); 276 277 workspace_filter = Gatherer.g_man.getFilter(workspace_tree); 278 workspace_filter.setBackground(Gatherer.config.getColor("coloring.workspace_heading_background", false)); 279 // Change the default colours of this filters combobox. 280 GComboBox fcb = workspace_filter.getComboBox(); 281 fcb.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_background", false)); 282 fcb.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 283 fcb.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_background", false)); 284 fcb.setTextSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_foreground", false)); 285 fcb = null; 286 287 // Collection Tree 288 collection_pane = new JPanel(); 289 collection_pane.setMinimumSize(MIN_SIZE); 290 collection_pane.setPreferredSize(TREE_SIZE); 291 collection_pane.setSize(TREE_SIZE); 292 293 args = new String[1]; 294 args[0] = get("Collection.No_Collection"); 295 collection_label = new JLabel(get("Collection", args)); 296 collection_label.setOpaque(true); 297 298 collection = Gatherer.c_man.getRecordSet(); 299 if(collection != null) { 300 collection_tree = new DragTree(Utility.COLLECTION_TREE, collection, null); 301 collection_tree.setEnabled(true); 302 } 303 else { 304 collection_tree = new DragTree(Utility.COLLECTION_TREE, null); 305 collection_tree.setEnabled(false); 306 } 307 group.add(collection_tree); 308 collection_tree.addFocusListener(this); 309 collection_tree.addKeyListener(key_listener); 310 collection_tree.addMouseListener(mouse_listener); 311 collection_tree.addMouseListener(Gatherer.g_man.foa_listener); 312 collection_tree.addTreeSelectionListener(file_queue); 313 collection_tree.addTreeExpansionListener(Gatherer.g_man.foa_listener); 314 collection_tree.putClientProperty("JTree.lineStyle", "Angled"); 315 collection_tree.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.collection_tree_background", false)); 316 collection_tree.setTextNonSelectionColor(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 317 collection_tree.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 318 collection_tree.setTextSelectionColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 319 collection_tree.setRootVisible(false); 320 321 collection_scroll = new JScrollPane(collection_tree); 322 323 collection_filter = Gatherer.g_man.getFilter(collection_tree); 324 if(collection != null) { 325 collection_filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false)); 326 } 327 else { 328 collection_filter.setBackground(Color.lightGray); 329 } 330 // Change the default colours of this filters combobox. 331 fcb = collection_filter.getComboBox(); 332 fcb.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.collection_tree_background", false)); 333 fcb.setTextNonSelectionColor(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 334 fcb.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 335 fcb.setTextSelectionColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 336 fcb = null; 337 338 tree_pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 339 340 // Status pane 341 control_pane = new JPanel(); 342 343 JPanel inner_pane = new JPanel(); 344 inner_pane.setSize(STATUS_SIZE); 345 346 JPanel file_pane = new JPanel(); 347 file_pane.setBackground(Color.white); 348 //JPanel job_pane = new JPanel(); 349 //job_pane.setBackground(Color.white); 350 JPanel progress_pane = new JPanel(); 351 progress_pane.setBackground(Color.white); 352 JLabel file_status = file_queue.getFileStatus(); 353 //JLabel job_status = job_queue.getJobStatus(); 354 355 JProgressBar progress = file_queue.getProgress(); 356 357 JPanel button_pane = new JPanel(); 358 359 bin_button = Gatherer.c_man.undo; 360 bin_button.addActionListener(this); 361 bin_button.setEnabled(false); 362 bin_button.setMinimumSize(MIN_SIZE); 363 bin_button.setPreferredSize(MIN_SIZE); 364 group.add(bin_button); 365 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 366 // Layout Components. 367 workspace_pane.setLayout(new BorderLayout()); 368 workspace_pane.add(workspace_label, BorderLayout.NORTH); 369 workspace_pane.add(workspace_scroll, BorderLayout.CENTER); 370 workspace_pane.add(workspace_filter, BorderLayout.SOUTH); 371 372 collection_pane.setLayout(new BorderLayout()); 373 collection_pane.add(collection_label, BorderLayout.NORTH); 374 collection_pane.add(collection_scroll, BorderLayout.CENTER); 375 collection_pane.add(collection_filter, BorderLayout.SOUTH); 376 377 tree_pane.add(workspace_pane, JSplitPane.LEFT); 378 tree_pane.add(collection_pane, JSplitPane.RIGHT); 379 tree_pane.setDividerLocation(TREE_SIZE.width - 10); 380 381 //job_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 382 //job_pane.setLayout(new BorderLayout()); 383 //job_pane.add(job_status, BorderLayout.CENTER); 384 385 file_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 386 file_pane.setLayout(new BorderLayout()); 387 file_pane.add(file_status, BorderLayout.CENTER); 388 389 progress_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 390 progress_pane.setLayout(new BorderLayout()); 391 progress_pane.add(progress, BorderLayout.CENTER); 392 393 inner_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10,10,10,10), BorderFactory.createLoweredBevelBorder())); 394 inner_pane.setLayout(new GridLayout(2,1)); 395 //inner_pane.add(job_pane); 396 inner_pane.add(file_pane); 397 inner_pane.add(progress_pane); 398 399 button_pane.add(cancel_action); 400 button_pane.add(new_folder); 401 button_pane.add(bin_button); 402 403 control_pane.setLayout(new BorderLayout()); 404 //control_pane.add(new_folder, BorderLayout.WEST); 405 control_pane.add(inner_pane, BorderLayout.CENTER); 406 control_pane.add(button_pane, BorderLayout.EAST); 407 408 this.setLayout(new BorderLayout()); 409 this.add(tree_pane, BorderLayout.CENTER); 410 this.add(control_pane, BorderLayout.SOUTH); 411 } 412 /** This method ensures that a certain tree path is visible and selected within the collection tree, expanding nodes if necessary. If the method is successful the bounds of the new selection are returned. */ 413 public Rectangle expandPath(TreePath path) { 414 collection_tree.setImmediate(true); 415 collection_tree.scrollPathToVisible(path); 416 collection_tree.setSelectionPath(path); 417 collection_tree.setImmediate(false); 418 return collection_tree.getRowBounds(collection_tree.getRowForPath(path)); 419 } 420 /** Called whenever this pane gains focus, this method ensures that the various tree renderers are correctly colouring the tree (as these settings sometimes get lost). 421 421 * @param event A <strong>FocusEvent</strong> containing details about the focus action performed. 422 422 */ 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 423 public void focusGained(FocusEvent event) { 424 DefaultTreeCellRenderer def = new DefaultTreeCellRenderer(); 425 DefaultTreeCellRenderer w = (DefaultTreeCellRenderer)workspace_tree.getCellRenderer(); 426 DefaultTreeCellRenderer c = (DefaultTreeCellRenderer)collection_tree.getCellRenderer(); 427 if(event.getSource() == workspace_tree) { 428 w.setBackgroundSelectionColor(def.getBackgroundSelectionColor()); 429 c.setBackgroundSelectionColor(Color.lightGray); 430 } 431 else if(event.getSource() == collection_tree) { 432 c.setBackgroundSelectionColor(def.getBackgroundSelectionColor()); 433 w.setBackgroundSelectionColor(Color.lightGray); 434 } 435 repaint(); 436 } 437 /** Implementation side-effect, not used in any way. 438 438 * @param event A <strong>FocusEvent</strong> containing details about the focus action performed. 439 439 */ 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 440 public void focusLost(FocusEvent event) { 441 } 442 /** Retrieve a list of the currently selected file records in the active tree. */ 443 public FileNode[] getSelected() { 444 TreePath paths[] = collection_tree.getSelectionPaths(); 445 FileNode records[] = null; 446 if(paths != null) { 447 records = new FileNode[paths.length]; 448 for(int i = 0; i < records.length; i++) { 449 records[i] = (FileNode) paths[i].getLastPathComponent(); 450 } 451 } 452 return records; 453 } 454 455 public String getSelectionDetails() { 456 return collection_tree.getSelectionDetails(); 457 } 458 459 public DragTree getWorkspaceTree() { 460 return workspace_tree; 461 } 462 463 public void refreshTrees() { 464 collection_tree.refresh(null); 465 } 466 467 /** Retrieve a phrase from the dictionary based on the key. 468 468 * @param key A <strong>String</strong> used to uniquely identify the phrase to be retrieved. 469 469 */ 470 471 472 473 470 private String get(String key) { 471 return get(key, null); 472 } 473 /** Retrieve a phrase from the dictionary based on the key, and filled in using text fragments from an arguments array. 474 474 * @param key A <strong>String</strong> used to uniquely identify the phrase to be retrieved. 475 475 * @param args A <strong>String[]</strong> used as parameters to be inserted in the phrase retrieved. … … 477 477 * @see org.greenstone.gatherer.Gatherer 478 478 */ 479 480 481 482 483 484 485 479 private String get(String key, String args[]) { 480 if(key.indexOf('.') == -1) { 481 key = "Collection." + key; 482 } 483 return Gatherer.dictionary.get(key, args); 484 } 485 /** Used to set the enabled state, and hence the colouring, of the two tree labels. 486 486 * @param label The <strong>JLabel</strong> to be affected. 487 487 * @param state <i>true</i> for enabled, i.e. when a collection is ready, <i>false</i> otherwise. … … 489 489 * @param background The <strong>Color</strong> to make the background of the label when enabled. 490 490 */ 491 492 493 494 495 496 497 498 499 500 501 502 503 504 491 private void setEnabled(JLabel label, boolean state, Color foreground, Color background) { 492 ///ystem.err.println("Setting the label color to state " + state); 493 if(state) { 494 label.setBackground(background); 495 label.setForeground(foreground); 496 } 497 else { 498 label.setBackground(Color.lightGray); 499 label.setForeground(Color.black); 500 } 501 label.repaint(); 502 ///ystem.err.println("Color is now " + label.getBackground()); 503 } 504 /** When a user right-clicks within the trees on the collection pane view they are presented with a small popup menu of context based options. This class provides such functionality. 505 505 */ 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 506 private class GPopupMenu 507 extends JPopupMenu 508 implements ActionListener { 509 /** The tree over which the right click action occured. */ 510 private DragTree tree = null; 511 /** The file record over which the right click action occured, if any. */ 512 private FileNode node = null; 513 /** A menu item enabled if a delete action is appropriate in the menus current context. */ 514 private JMenuItem delete = null; 515 /** A menu item enabled if a special directory mapping is appropriate in the menus current context. */ 516 private JMenuItem map = null; 517 /** A menu item enabled if a new folder action is appropriate in the menus current context. */ 518 private JMenuItem new_folder = null; 519 /** A menu item enabled if a show meta-audit dialog action is appropriate in the menus current context. */ 520 private JMenuItem show_metaaudit = null; 521 /** A menu item allowing a user to unmap a special directory, if and only if a special directory is selected. */ 522 private JMenuItem unmap = null; 523 /** Constructor. */ 524 public GPopupMenu(DragTree tree, MouseEvent event) { 525 super(); 526 this.tree = tree; 527 TreePath path = tree.getClosestPathForLocation(event.getX(), event.getY()); 528 node = (FileNode)path.getLastPathComponent(); 529 529 // Set Options based on selection and tree 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 530 if(tree.getSelectionCount() != 0 && tree == collection_tree) { 531 show_metaaudit = new JMenuItem(get("Menu.Metadata_View") + " " + collection_tree.getSelectionDetails(), KeyEvent.VK_V); 532 show_metaaudit.addActionListener(this); 533 add(show_metaaudit); 534 } 535 if(tree == collection_tree && node != null && node.getFile() != null && node.getFile().isDirectory() && !node.isReadOnly()) { 536 new_folder = new JMenuItem(get("New_Folder"), KeyEvent.VK_N); 537 new_folder.addActionListener(this); 538 add(new_folder); 539 add(new JSeparator()); 540 } 541 if(node == null || (node != null && !node.isReadOnly())) { 542 delete = new JMenuItem(get("Delete"), KeyEvent.VK_D); 543 delete.addActionListener(this); 544 add(delete); 545 } 546 if(tree == workspace_tree && node != null && !node.isLeaf()) { 547 String node_name = node.toString(); 548 FileNode root = (FileNode) tree.getModel().getRoot(); 549 if(!node_name.equals(get("Tree.World")) && !node_name.equals(get("Tree.Root")) && !node_name.equals(get("Tree.Public")) && !node_name.equals(get("Tree.Private"))) { 550 // You can unmap 1st level nodes. 551 if(root.getIndex(node) != -1) { 552 unmap = new JMenuItem(get("MappingPrompt.Unmap"), KeyEvent.VK_U); 553 unmap.addActionListener(this); 554 add(unmap); 555 } 556 // Or map any other level directories. 557 else { 558 map = new JMenuItem(get("MappingPrompt.Map"), KeyEvent.VK_M); 559 map.addActionListener(this); 560 add(map); 561 } 562 } 563 } 564 show(tree, event.getX(), event.getY()); 565 } 566 /** Called whenever one of the menu items is actioned apon, this method then causes the appropriate effect. */ 567 public void actionPerformed(ActionEvent event) { 568 if(event.getSource() == delete) { 569 // Retrieve the selection. Of course this gets a bit tricky as the user may have right clicked over a node not in the current selection, in which case we remove only that node. 570 TreePath[] selection_paths = tree.getSelectionPaths(); 571 if(selection_paths != null) { 572 FileNode[] source_nodes = new FileNode[selection_paths.length]; 573 boolean found = false; 574 for(int i = 0; i < selection_paths.length; i++) { 575 source_nodes[i] = (FileNode) selection_paths[i].getLastPathComponent(); 576 if(node != null) { 577 found = found || source_nodes[i].equals(node); 578 } 579 } 580 if(node != null && !found) { 581 source_nodes = null; 582 source_nodes = new FileNode[1]; 583 source_nodes[0] = node; 584 } 585 // Fire a delete action 586 Gatherer.f_man.action(tree, source_nodes, bin_button, null); 587 source_nodes = null; 588 } 589 selection_paths = null; 590 } 591 else if(event.getSource() == map && node != null) { 592 MappingPrompt mp = new MappingPrompt(node.getFile()); 593 mp.destroy(); 594 mp = null; 595 } 596 else if(event.getSource() == new_folder && node != null) { 597 Gatherer.f_man.newFolder(tree, node); 598 } 599 else if(event.getSource() == show_metaaudit) { 600 Gatherer.g_man.showMetaAuditBox(); 601 } 602 else if(event.getSource() == unmap && node != null) { 603 Gatherer.c_man.removeDirectoryMapping(node); 604 } 605 } 606 /** Retrieve a phrase from the dictionary based on the key. 607 607 * @param key A <strong>String</strong> used to uniquely identify the phrase to be retrieved. 608 608 */ 609 610 611 612 609 private String get(String key) { 610 return get(key, null); 611 } 612 /** Retrieve a phrase from the dictionary based on the key, and filled in using text fragments from an arguments array. 613 613 * @param key A <strong>String</strong> used to uniquely identify the phrase to be retrieved. 614 614 * @param args A <strong>String[]</strong> used as parameters to be inserted in the phrase retrieved. … … 616 616 * @see org.greenstone.gatherer.Gatherer 617 617 */ 618 619 620 621 622 623 624 625 626 627 628 629 618 private String get(String key, String args[]) { 619 if(key.indexOf('.') == -1) { 620 key = "CollectionPopupMenu." + key; 621 } 622 return Gatherer.dictionary.get(key, args); 623 } 624 } 625 /** This class listens for certain key presses, such as [Enter] or [Delete], and responds appropriately. */ 626 private class KeyListenerImpl 627 extends KeyAdapter { 628 /** Called whenever a key that was pressed is released, it is this action that will cause the desired effects (this allows for the key event itself to be processed prior to this listener dealing with it). */ 629 public void keyReleased(KeyEvent event) { 630 630 ///ystem.err.println("Key Release detected. " + event.getKeyCode()); 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 631 if(event.getKeyCode() == KeyEvent.VK_DELETE) { 632 // Get the selected files from the tree and removal them using the default dnd removal method. 633 // Find the active tree (you've made selections in). 634 DragTree tree = (DragTree) group.getActive(); 635 // Fudge things a bit 636 group.setSource(tree); 637 // Determine the selection. 638 TreePath paths[] = tree.getSelectionPaths(); 639 if(paths != null) { 640 FileNode[] source_nodes = new FileNode[paths.length]; 641 for(int i = 0; i < source_nodes.length; i++) { 642 source_nodes[i] = (FileNode) paths[i].getLastPathComponent(); 643 } 644 Gatherer.f_man.action(tree, source_nodes, bin_button, null); 645 source_nodes = null; 646 } 647 } 648 else if(event.getKeyCode() == KeyEvent.VK_ENTER) { 649 // Get the first selected file. 650 DragTree tree = (DragTree)event.getSource(); 651 TreePath path = tree.getSelectionPath(); 652 if(path != null) { 653 File file = ((FileNode)path.getLastPathComponent()).getFile(); 654 if(file.isFile()) { 655 Gatherer.self.spawnApplication(file); 656 } 657 } 658 } 659 } 660 } 661 662 /** This provides a small prompt for gathering addition details about a special directory mapping such as its symbolic name. */ 663 private class MappingPrompt 664 extends JDialog 665 implements ActionListener, KeyListener { 666 private boolean cancelled = false; 667 private JButton cancel_button = null; 668 private JButton ok_button = null; 669 private JTextField name_field = null; 670 public MappingPrompt(File file) { 671 super(Gatherer.g_man); 672 setModal(true); 673 setSize(DIALOG_SIZE); 674 setTitle(get("MappingPrompt.Title")); 675 675 // Creation 676 677 678 679 680 681 682 683 684 685 686 687 688 689 676 JPanel content_pane = (JPanel) getContentPane(); 677 JPanel center_pane = new JPanel(); 678 JPanel file_pane = new JPanel(); 679 JLabel file_label = new JLabel(get("MappingPrompt.File")); 680 file_label.setPreferredSize(LABEL_SIZE); 681 JLabel file_field = new JLabel(file.getAbsolutePath()); 682 JPanel name_pane = new JPanel(); 683 JLabel name_label = new JLabel(get("MappingPrompt.Name")); 684 name_label.setPreferredSize(LABEL_SIZE); 685 name_field = new JTextField(file.getName()); 686 JPanel button_pane = new JPanel(); 687 ok_button = new JButton(get("General.OK")); 688 ok_button.setEnabled(name_field.getText().length() > 0); 689 cancel_button = new JButton(get("General.Cancel")); 690 690 // Connection 691 692 693 691 cancel_button.addActionListener(this); 692 ok_button.addActionListener(this); 693 name_field.addKeyListener(this); 694 694 // Layout 695 696 697 695 file_pane.setLayout(new BorderLayout()); 696 file_pane.add(file_label, BorderLayout.WEST); 697 file_pane.add(file_field, BorderLayout.CENTER); 698 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 699 name_pane.setLayout(new BorderLayout()); 700 name_pane.add(name_label, BorderLayout.WEST); 701 name_pane.add(name_field, BorderLayout.CENTER); 702 703 center_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); 704 center_pane.setLayout(new GridLayout(2,1,5,5)); 705 center_pane.add(file_pane); 706 center_pane.add(name_pane); 707 708 button_pane.setLayout(new GridLayout(1,2,5,5)); 709 button_pane.add(ok_button); 710 button_pane.add(cancel_button); 711 712 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 713 content_pane.setLayout(new BorderLayout()); 714 content_pane.add(center_pane, BorderLayout.CENTER); 715 content_pane.add(button_pane, BorderLayout.SOUTH); 716 716 // Display 717 718 719 717 Dimension screen_size = Gatherer.config.screen_size; 718 setLocation((screen_size.width - DIALOG_SIZE.width) / 2, (screen_size.height - DIALOG_SIZE.height) / 2); 719 show(); 720 720 // If not cancelled create mapping. 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 721 if(!cancelled) { 722 Gatherer.c_man.addDirectoryMapping(name_field.getText(), file); 723 } 724 } 725 public void actionPerformed(ActionEvent event) { 726 if(event.getSource() == cancel_button) { 727 cancelled = true; 728 } 729 dispose(); 730 } 731 public void destroy() { 732 cancel_button = null; 733 ok_button = null; 734 name_field = null; 735 } 736 public void keyPressed(KeyEvent event) { 737 } 738 public void keyReleased(KeyEvent event) { 739 ok_button.setEnabled(name_field.getText().length() > 0); 740 741 } 742 public void keyTyped(KeyEvent event) { 743 } 744 } 745 /** This class listens for mouse clicks and responds right mouse button clicks (popup menu). */ 746 private class MouseListenerImpl 747 extends MouseAdapter { 748 /** Any subclass of MouseAdapter can override this method to respond to mouse click events. In this case we want to open a pop-up menu if we detect a right mouse click over one of our registered components, and start an external application if someone double clicks on a certain file record. */ 749 public void mouseClicked(MouseEvent event) { 750 if(SwingUtilities.isRightMouseButton(event)) { 751 new GPopupMenu((DragTree)event.getSource(), event); 752 } 753 } 754 } 755 755 } -
trunk/gli/src/org/greenstone/gatherer/gui/Coloring.java
r4293 r4367 57 57 */ 58 58 public class Coloring 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 59 implements Serializable { 60 /** The color of a buttons background. */ 61 public Color button_background; 62 /** The color of a buttons foreground. */ 63 public Color button_foreground; 64 /** The background color used to indicate that a button has been clicked or selected. */ 65 public Color button_selected_background; 66 /** The foreground color used to indicate that a button has been clicked or selected. */ 67 public Color button_selected_foreground; 68 /** The color used for the background of the collection label. */ 69 public Color collection_heading_background = null; 70 /** The color used for the text of the collection label. */ 71 public Color collection_heading_foreground = null; 72 /** The color used for the background of controls in the collection that are non-editable. */ 73 public Color collection_noneditable_background = null; 74 /** The color used for the foreground of controls in the collection that are non-editable. */ 75 public Color collection_noneditable_foreground = null; 76 /** The color used for the background of a selection from the collection. */ 77 public Color collection_selection_background = null; 78 /** The color used for the text of a selection from the collection. */ 79 public Color collection_selection_foreground = null; 80 /** The color used for the background of a collection oriented component. */ 81 public Color collection_tree_background = null; 82 /** The color used for the text of a collection oriented component. */ 83 public Color collection_tree_foreground = null; 84 /** The color used for the background of an error state oriented component. */ 85 public Color error_background; 86 /** The color used for the text of an error state oriented component. */ 87 public Color error_foreground; 88 /** The color used for the background (behind the slider) part of a scroll bar. */ 89 public Color scrollbar_background; 90 /** The color usef for the foreground (slider and arrows) parts of a scroll bar. */ 91 public Color scrollbar_foreground; 92 /** The color used for the background of the workspace label. */ 93 public Color workspace_heading_background = null; 94 /** The color used for the text of the workspace label. */ 95 public Color workspace_heading_foreground = null; 96 /** The color used for the background of a selection from the workspace. */ 97 public Color workspace_selection_background = null; 98 /** The color used for the text of a selection from the workspace. */ 99 public Color workspace_selection_foreground = null; 100 /** The color used for the background of a workspace oriented component. */ 101 public Color workspace_tree_background = null; 102 /** The color used for the text of a workspace oriented component. */ 103 public Color workspace_tree_foreground = null; 104 /** Constructor. Uses default colors. 105 */ 106 public Coloring() { 107 // Default Values. 108 // Collection 109 collection_heading_background = new Color(176, 208, 176); 110 collection_heading_foreground = Color.black; 111 collection_selection_background = new Color(128, 180, 216); 112 collection_selection_foreground = Color.black; 113 collection_tree_background = new Color(224, 240, 224); 114 collection_tree_foreground = Color.black; 115 collection_noneditable_background = Color.lightGray; 116 collection_noneditable_foreground = Color.black; 117 // Other 118 button_background = Color.white; 119 button_foreground = Color.black; 120 button_selected_background = new Color(128, 180, 216); 121 button_selected_foreground = Color.white; 122 error_background = new Color(250, 180, 180); 123 error_foreground = Color.red; 124 scrollbar_background = Color.lightGray; 125 scrollbar_foreground = Color.white; 126 // Workspace 127 workspace_heading_background = new Color(128, 180, 216); 128 workspace_heading_foreground = Color.black; 129 workspace_selection_background = new Color(176, 208, 176); 130 workspace_selection_foreground = Color.black; 131 workspace_tree_background = new Color(218, 237, 252); 132 workspace_tree_foreground = Color.black; 133 } 134 134 } -
trunk/gli/src/org/greenstone/gatherer/gui/ComboArea.java
r4293 r4367 49 49 */ 50 50 public class ComboArea 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 51 extends JPanel { 52 /** Should the listener ignore any change events fired (most likely as a result of the listener in the first place). */ 53 private boolean ignore = false; 54 /** The combobox we are going to utilize. */ 55 private SteppedComboBox combobox = null; 56 /** The text area involved. Not quite a JTextArea, the smarter part is that is allows coloring contrary to the UIManager settings. */ 57 private SmarterTextArea text_area = null; 58 /** Create a new ComboArea demarked by a particular label. The label is given here so that it fits nicely with the text area and button. 59 * @param text The label text to be shown above text area as a <strong>String</strong>. 60 * @param label_size The <strong>Dimension</strong> to use for the label. 61 * @see jp.gr.java_conf.tame.swing.combobox.SteppedComboBox 62 * @see org.greenstone.gatherer.gui.ComboArea.ComboAreaListener 63 * @see org.greenstone.gatherer.gui.ComboArea.Renderer 64 */ 65 public ComboArea(String text, Dimension label_size) { 66 // Creation 67 JPanel title_pane = new JPanel(); 68 title_pane.setOpaque(false); 69 JLabel label = new JLabel(text); 70 label.setOpaque(false); 71 label.setPreferredSize(label_size); 72 JPanel text_pane = new JPanel(); 73 text_area = new SmarterTextArea(); 74 text_area.setRows(3); 75 JPanel button_pane = new JPanel(); 76 Dimension button_size = new Dimension(label_size.height, label_size.height); 77 button_pane.setMaximumSize(button_size); 78 button_pane.setMinimumSize(button_size); 79 button_pane.setPreferredSize(button_size); 80 button_pane.setSize(button_size); 81 combobox = new SteppedComboBox(Gatherer.self, button_size); 82 combobox.setDependant(text_area); 83 combobox.setPreferredSize(label_size); 84 combobox.setRenderer(new Renderer()); 85 // Connection 86 combobox.addActionListener(new ComboAreaListener()); 87 // Layout 88 title_pane.setLayout(new BorderLayout()); 89 title_pane.add(label, BorderLayout.WEST); 90 90 91 92 91 button_pane.setLayout(new BorderLayout()); 92 button_pane.add(combobox.getButton(), BorderLayout.CENTER); 93 93 94 95 96 94 text_pane.setLayout(new BorderLayout()); 95 text_pane.add(new JScrollPane(text_area), BorderLayout.CENTER); 96 text_pane.add(button_pane, BorderLayout.EAST); 97 97 98 99 100 101 102 98 setLayout(new BorderLayout()); 99 add(title_pane, BorderLayout.NORTH); 100 add(text_pane, BorderLayout.CENTER); 101 } 102 /** Add an element to our combobox model. Remember to tell the listeners to ignore this action unless you want an infinite loop. 103 103 * @param item The <strong>Object</strong> to add. 104 104 */ 105 106 107 108 109 110 111 */ 112 113 114 115 105 public void add(Object item) { 106 ignore = true; 107 combobox.add(item.toString()); 108 ignore = false; 109 } 110 /** Clear the combobox model. 111 */ 112 public void clear() { 113 combobox.clear(); 114 } 115 /** Retrieve the text currently displayed in the text area. 116 116 * @return A <strong>String</strong> containing the required text. 117 117 */ 118 119 120 121 118 public String getText() { 119 return text_area.getText(); 120 } 121 /** Retrieve a reference to the text area. 122 122 * @return A <strong>JTextComponent</strong> reference. 123 123 */ 124 125 126 127 124 public JTextComponent getTextComponent() { 125 return text_area; 126 } 127 /** Change the selected item in the combobox to the one given. If such an object doesn't exist in the model, ignore it. Notice that this time we don't ignore, as we want a selection to update the text field. 128 128 * @param item The <strong>Object</strong> that we want to select from the combobox. 129 129 */ 130 131 132 133 130 public void setSelectedItem(Object item) { 131 combobox.setSelectedItem(item); 132 } 133 /** Set the text shown in the text area to the value provided. Note that this has no effect on the combobox, nor will this value be stored in the model. 134 134 * @param text The <strong>String</strong> to display. 135 135 */ 136 137 138 139 140 141 142 143 136 public void setText(String text) { 137 text_area.setText(text); 138 } 139 /** This clas listens for changes in the selected item in the combobox and if applicable updates the text area to match. */ 140 private class ComboAreaListener 141 implements ActionListener { 142 /** Whenever a new object is selected from the combobox list, determine if this is an appropriate time to update the text area and if so do so. 143 * @param event An <strong>ActionEvent</strong> encompassing all the relevant data about an action having been performed. 144 144 */ 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 145 public void actionPerformed(ActionEvent event) { 146 Object object = combobox.getSelectedItem(); 147 if(object != null && !ignore) { 148 text_area.setText(object.toString()); 149 } 150 } 151 } 152 /** This renderer is used to ensure that the labels shown in the combobox drop-down list are both correct in colouring and legible. The later is important as the entry itself may actually span several lines. */ 153 private class Renderer 154 extends DefaultListCellRenderer { 155 /** Retrieve the component used to 'rubberstamp' the desired entry in the combobox. 156 * @param list The <strong>JList</strong> this component will be renderer in. 157 * @param value The <strong>Object</strong> whose value should be represented by the component returned. 158 * @param index An <i>int</i> giving the objects index in the list of objects. 159 * @param isSelected <i>true</i> if this object is currently selected, <i>false</i> otherwise. 160 * @param cellHasFocus <i>true</i> if this object is currently in focus, <i>false</i> otherwise. 161 * @see org.greenstone.gatherer.util.Utility 162 */ 163 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 164 JLabel temp = null; 165 if(value != null) { 166 // Only show a single line by removing new lines. 167 StringBuffer text = new StringBuffer(Utility.stripNL((String)value)); 168 // Generate prototype label 169 temp = (JLabel) super.getListCellRendererComponent(list, text.toString(), index, isSelected, cellHasFocus); 170 // Trim down the value string so it fits nicely. Start by shortening it to the number of characters determined from the smarter text area. 171 int preferred_characters = text_area.calculateColumnCount(); 172 if(preferred_characters > 3 && text.length() > preferred_characters) { 173 text.delete(preferred_characters - 3, text.length()); 174 text.append("..."); 175 } 176 temp.setText(text.toString()); 177 // If we are still too long, shorten by one character at a time until it fits 178 while(temp.getPreferredSize().width > text_area.getSize().width && text.length() > 4) { 179 // Remove the last four characters and mark as being chopped 180 text.delete(text.length() - 4, text.length()); 181 text.append("..."); 182 // Assign new string, rinse and repeat. 183 temp.setText(text.toString()); 184 } 185 } 186 else { 187 temp = (JLabel) super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus); 188 } 189 189 // Colouring should be the same as the dependant we are based on. 190 191 192 193 194 195 196 197 198 199 200 190 if(isSelected) { 191 temp.setBackground(text_area.getSelectionColor()); 192 temp.setForeground(text_area.getSelectedTextColor()); 193 } 194 else { 195 temp.setBackground(text_area.getBackground()); 196 temp.setForeground(text_area.getForeground()); 197 } 198 return temp; 199 } 200 } 201 201 } 202 203 -
trunk/gli/src/org/greenstone/gatherer/gui/CreatePane.java
r4346 r4367 80 80 */ 81 81 public class CreatePane 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 82 extends JPanel 83 implements GShellListener { 84 /** Determines the current view that should be shown for this pane. */ 85 public boolean processing = false; 86 /** The options pane generates all the various option sheet configuations. */ 87 public OptionsPane options_pane = null; 88 /** A card layout is used to store the separate configuration and progress panes. */ 89 private CardLayout card_layout = null; 90 /** This monitor tracks the build processes progress. */ 91 private GShellProgressMonitor build_monitor = null; 92 /** This monitor tracks the copy processes progress. */ 93 private GShellProgressMonitor copy_monitor = null; 94 /** This monitor tracks the import processes progress. */ 95 private GShellProgressMonitor import_monitor = null; 96 /** The button for begining the building processes. */ 97 private JButton build_button = null; 98 /** The button for stopping the building processes. */ 99 private JButton cancel_button = null; 100 /** The label displaying the number of documents in this collection. */ 101 private JLabel document_count = null; 102 /** The label alongside the build progress bar gets some special treatment so... */ 103 private JLabel progress_build_label = null; 104 /** The label alongside the copy progress bar gets some special treatment so... */ 105 private JLabel progress_copy_label = null; 106 /** The label alongside the import progress bar gets some special treatment so... */ 107 private JLabel progress_import_label = null; 108 /** The pane which contains the controls for configuration. */ 109 private JPanel control_pane = null; 110 /** The pane which has the card layout as its manager. */ 111 private JPanel main_pane = null; 112 /** The pane which contains the progress information. */ 113 private JPanel progress_pane = null; 114 114 /** the pane on the right-hand side - shows the requested options view */ 115 115 private JPanel right = null; 116 116 /** This pane is the one that is updated to show the requested options view. */ 117 117 //private JPanel target_pane = null; 118 118 /** The scrolling pane the log is inside. */ … … 120 120 /** the scrolling pane the righthand side is inside - only used for import and build options. the log and log list are not inside a scrollpane */ 121 121 private JScrollPane scroll_pane; 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 122 /** The log for the current process. */ 123 private JTextArea process_log = null; 124 /** The message log for the entire session. */ 125 private JTextArea message_log = new JTextArea(); 126 /** A tree used to display the currently available option views. */ 127 private OptionTree tree = null; 128 /** An array used to pass arguments with dictionary calls. */ 129 private String args[] = null; 130 /** The size of the buttons at the bottom of the screen. */ 131 static private Dimension BUTTON_SIZE = new Dimension(386, 50); 132 /** The size of the labels on the progress pane. */ 133 static private Dimension LABEL_SIZE = new Dimension(140, 25); 134 /** An identifier for the control panel within the card layout. */ 135 static private String CONTROL = "Control"; 136 /** An identifier for the progress panel within the card layout. */ 137 static private String PROGRESS = "Progress"; 138 /** The constructor creates important helper classes, and initializes all the components. 139 * @see org.greenstone.gatherer.collection.CollectionManager 140 * @see org.greenstone.gatherer.gui.BuildOptions 141 * @see org.greenstone.gatherer.gui.CreatePane.BuildButtonListener 142 * @see org.greenstone.gatherer.gui.CreatePane.CancelButtonListener 143 * @see org.greenstone.gatherer.gui.CreatePane.OptionTree 144 * @see org.greenstone.gatherer.gui.OptionsPane 145 * @see org.greenstone.gatherer.shell.GBasicProgressMonitor 146 * @see org.greenstone.gatherer.shell.GBuildProgressMonitor 147 * @see org.greenstone.gatherer.shell.GImportProgressMonitor 148 * @see org.greenstone.gatherer.shell.GShellProgressMonitor 149 */ 150 public CreatePane() { 151 //this.target_pane = new JPanel(new BorderLayout()); 152 Collection collection = Gatherer.c_man.getCollection(); 153 //if(collection != null) { 154 // this.options_pane = new OptionsPane(message_log, collection.build_options); 155 // } 156 // Create components 157 card_layout = new CardLayout(); 158 // Control Pane 159 control_pane = new JPanel(); 160 args = new String[1]; 161 args[0] = "0"; 162 document_count = new JLabel(get("Document_Count", args)); 163 tree = new OptionTree(); 164 // Progress Pane 165 progress_pane = new JPanel(); 166 167 progress_copy_label = new JLabel(get("Copy_Progress")); 168 progress_copy_label.setForeground(Color.black); 169 progress_copy_label.setHorizontalAlignment(JLabel.LEFT); 170 progress_copy_label.setPreferredSize(LABEL_SIZE); 171 progress_copy_label.setMinimumSize(LABEL_SIZE); 172 progress_copy_label.setSize(LABEL_SIZE); 173 174 copy_monitor = new GBasicProgressMonitor(); 175 Gatherer.c_man.registerCopyMonitor(copy_monitor); 176 177 progress_import_label = new JLabel(get("Import_Progress")); 178 progress_import_label.setForeground(Color.black); 179 progress_import_label.setHorizontalAlignment(JLabel.LEFT); 180 progress_import_label.setPreferredSize(LABEL_SIZE); 181 progress_import_label.setMinimumSize(LABEL_SIZE); 182 progress_import_label.setSize(LABEL_SIZE); 183 184 import_monitor = new GImportProgressMonitor(); //GBasicProgressMonitor(); 185 Gatherer.c_man.registerImportMonitor(import_monitor); 186 187 progress_build_label = new JLabel(get("Build_Progress")); 188 progress_build_label.setForeground(Color.black); 189 progress_build_label.setHorizontalAlignment(JLabel.LEFT); 190 progress_build_label.setPreferredSize(LABEL_SIZE); 191 progress_build_label.setMinimumSize(LABEL_SIZE); 192 progress_build_label.setSize(LABEL_SIZE); 193 194 build_monitor = new GBuildProgressMonitor((GImportProgressMonitor)import_monitor); //GBasicProgressMonitor(); 195 Gatherer.c_man.registerBuildMonitor(build_monitor); 196 197 // Buttons. 198 build_button = new JButton(get("Build_Collection")); 199 build_button.addActionListener(new BuildButtonListener()); 200 build_button.setPreferredSize(BUTTON_SIZE); 201 cancel_button = new JButton(get("Cancel_Build")); 202 cancel_button.addActionListener(new CancelButtonListener()); 203 cancel_button.setEnabled(false); 204 cancel_button.setPreferredSize(BUTTON_SIZE); 205 } 206 /** This method is invoked at any time there has been a significant change in the collection, such as saving, loading or creating. 207 207 * @param ready A <strong>boolean</strong> indicating if a collection is currently available. 208 208 * @see org.greenstone.gatherer.Gatherer … … 211 211 * @see org.greenstone.gatherer.gui.OptionsPane 212 212 */ 213 214 215 213 public void collectionChanged(boolean ready) { 214 ///ystem.err.println("Collection changed... "); 215 if(Gatherer.c_man != null && Gatherer.c_man.ready()) { 216 216 217 218 219 220 221 222 223 224 225 217 if (!processing &&this.options_pane!=null) { 218 // we only do this if we are not processing - if we are processing, then we haven't added the new entry yet, and it will be added by another method 219 this.options_pane.resetLogList(); // saves any residual message 220 } 221 this.options_pane = new OptionsPane(message_log, Gatherer.c_man.getCollection().build_options); 222 tree.valueChanged(null); 223 } 224 } 225 /** This method is called to actually layout the components. 226 226 * @see org.greenstone.gatherer.Configuration 227 227 * @see org.greenstone.gatherer.Gatherer 228 228 */ 229 230 231 232 233 234 229 public void display() { 230 // Build control_pane 231 JPanel stats_area = new JPanel(); 232 stats_area.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createTitledBorder(get("Statistics_Title")))); 233 stats_area.setLayout(new GridLayout(1,1)); 234 stats_area.add(document_count); 235 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 236 JPanel left = new JPanel(); 237 left.setBorder(BorderFactory.createEmptyBorder(0,5,5,5)); 238 left.setLayout(new BorderLayout()); 239 left.add(tree, BorderLayout.CENTER); 240 241 right = new JPanel(); 242 right.setBorder(BorderFactory.createEmptyBorder(0,0,5,5)); 243 right.setLayout(new BorderLayout()); 244 //scroll_pane = new JScrollPane(target_pane); 245 //right.add(scroll_pane, BorderLayout.CENTER); 246 247 JPanel options_area = new JPanel(); 248 options_area.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createTitledBorder(get("Options_Title")))); 249 options_area.setLayout(new BorderLayout()); 250 options_area.add(left, BorderLayout.WEST); 251 options_area.add(right, BorderLayout.CENTER); 252 253 control_pane.setLayout(new BorderLayout()); 254 control_pane.add(options_area, BorderLayout.CENTER); 255 //control_pane.add(stats_area, BorderLayout.SOUTH); 256 257 // Build progress_pane 258 JPanel copy_pane = new JPanel(); 259 copy_pane.setLayout(new BorderLayout()); 260 copy_pane.add(progress_copy_label, BorderLayout.WEST); 261 copy_pane.add(copy_monitor.getProgress(), BorderLayout.CENTER); 262 263 JPanel import_pane = new JPanel(); 264 import_pane.setLayout(new BorderLayout()); 265 import_pane.add(progress_import_label, BorderLayout.WEST); 266 import_pane.add(import_monitor.getProgress(), BorderLayout.CENTER); 267 268 JPanel build_pane = new JPanel(); 269 build_pane.setLayout(new BorderLayout()); 270 build_pane.add(progress_build_label, BorderLayout.WEST); 271 build_pane.add(build_monitor.getProgress(), BorderLayout.CENTER); 272 273 JPanel bar_area = new JPanel(); 274 bar_area.setBorder(BorderFactory.createEmptyBorder(10,10,5,10)); 275 276 bar_area.setLayout(new GridLayout(2,2,10,5)); 277 bar_area.add(import_pane); 278 bar_area.add(build_pane); 279 280 281 progress_pane.setBorder(BorderFactory.createEmptyBorder(20,20,20,20)); 282 progress_pane.setLayout(new BorderLayout()); 283 progress_pane.add(bar_area, BorderLayout.NORTH); 284 285 // Main pane 286 main_pane = new JPanel(card_layout); 287 main_pane.add(control_pane, CONTROL); 288 main_pane.add(progress_pane, PROGRESS); 289 290 // Buttons 291 JPanel button_pane = new JPanel(); 292 button_pane.setBorder(BorderFactory.createEmptyBorder(5,10,10,10)); 293 button_pane.setLayout(new GridLayout(1,2)); 294 button_pane.add(build_button); 295 button_pane.add(cancel_button); 296 297 this.setLayout(new BorderLayout()); 298 this.add(main_pane, BorderLayout.CENTER); 299 this.add(button_pane, BorderLayout.SOUTH); 300 } 301 /** This method is called whenever the 'Create' tab is selected from the view bar. It allows this view to perform any preactions required prior to display. In this case this entails gathering up to date information about the status of the collection including number of documents etc. 302 302 * @see org.greenstone.gatherer.Gatherer 303 303 * @see org.greenstone.gatherer.collection.CollectionManager 304 304 * @see org.greenstone.gatherer.gui.CreatePane.OptionTree 305 305 */ 306 307 308 306 public void gainFocus() { 307 if(!processing) { 308 card_layout.show(main_pane, CONTROL); 309 309 //args = new String[1]; 310 310 //if(Gatherer.c_man.ready()) { … … 315 315 //} 316 316 //document_count.setText(get("Document_Count", args)); 317 318 319 320 321 322 323 317 } 318 // Refresh the set of controls. 319 TreePath path = tree.getSelectionPath(); 320 tree.clearSelection(); 321 tree.setSelectionPath(path); 322 } 323 /** Method to acquire the progress monitor associated with builds. 324 324 * @return The build <strong>GShellProgressMonitor</strong>. 325 325 */ 326 327 328 329 326 public GShellProgressMonitor getBuildProgress() { 327 return build_monitor; 328 } 329 /** Method to acquire the progress monitor associated with copying. 330 330 * @return The copying <strong>GShellProgressMonitor</strong>. 331 331 */ 332 333 334 335 332 public GShellProgressMonitor getCopyProgress() { 333 return copy_monitor; 334 } 335 /** Method to acquire the progress monitor associated with import. 336 336 * @return The import <strong>GShellProgressMonitor</strong>. 337 337 */ 338 339 340 341 342 343 344 345 346 347 338 public GShellProgressMonitor getImportProgress() { 339 return import_monitor; 340 } 341 342 /** We are informed when this view pane loses focus so we can update build options. */ 343 public void loseFocus() { 344 tree.valueChanged(null); 345 } 346 347 /** All implementation of GShellListener must include this method so the listener can be informed of messages from the GShell. 348 348 * @param event A <strong>GShellEvent</strong> that contains, amoung other things, the message. 349 349 */ 350 351 352 353 354 355 356 350 public synchronized void message(GShellEvent event) { 351 ///ystem.err.println("Recieved message: " + event.getMessage()); 352 String text = event.getMessage(); 353 message_log.append(text + "\n"); 354 if(process_log != null) { 355 process_log.append(text + "\n"); 356 process_log.setCaretPosition(process_log.getCaretPosition() + text.length() + 1); 357 357 //scroll_log.getVerticalScrollBar().setValue(process_log.getHeight() - process_log.getVisibleRect().height); 358 359 360 358 } 359 } 360 /** All implementation of GShellListener must include this method so the listener can be informed when a GShell begins its task. Implementation side-effect, not actually used. 361 361 * @param event A <strong>GShellEvent</strong> that contains details of the initial state of the <strong>GShell</strong> before task comencement. 362 362 */ 363 364 365 366 363 public synchronized void processBegun(GShellEvent event) { 364 // We don't care. We'll get a more acurate start from the progress monitors. 365 } 366 /** All implementation of GShellListener must include this method so the listener can be informed when a GShell completes its task. 367 367 * @param event A <strong>GShellEvent</strong> that contains details of the final state of the <strong>GShell</strong> after task completion. 368 368 */ … … 381 381 } 382 382 } 383 383 /** This method retrieves a phrase from the dictionary based apon the key. 384 384 * @param key A <strong>String</strong> used as a reference to the correct phrase. 385 385 * @return A phrase, matching the key, as a <strong>String</strong>. 386 386 */ 387 388 389 390 387 private String get(String key) { 388 return get(key, null); 389 } 390 /** This method retrieves a phrase from the dictionary based apon the key and arguments. 391 391 * @param key A <strong>String</strong> used as a reference to the correct phrase. 392 392 * @param args A <strong>String[]</strong> whose contents are often substituted into the phrase before it is returned. … … 395 395 * @see org.greenstone.gatherer.Gatherer 396 396 */ 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 397 private String get(String key, String args[]) { 398 if(key.indexOf(".") == -1) { 399 key = "CreatePane." + key; 400 } 401 return Gatherer.dictionary.get(key, args); 402 } 403 /** This class serves as the listener for actions on the build button. */ 404 private class BuildButtonListener 405 implements ActionListener { 406 /** This method causes a call to be made to CollectionManager.importCollection(), which then imports and builds the collection as necessary. 407 * @param event An <strong>ActionEvent</strong> who, thanks to the power of object oriented programming, we don't give two hoots about. 408 * @see org.greenstone.gatherer.Gatherer 409 * @see org.greenstone.gatherer.collection.CollectionManager 410 * @see org.greenstone.gatherer.gui.BuildOptions 411 * @see org.greenstone.gatherer.shell.GShellProgressMonitor 412 */ 413 public void actionPerformed(ActionEvent event) { 414 414 // First we force the build options to be updated if we haven't already. 415 415 tree.valueChanged(null); 416 416 // Now go about building. 417 418 417 build_button.setEnabled(false); 418 cancel_button.setEnabled(true); 419 419 // Create a new process log, and place it. 420 421 422 423 424 425 420 if(scroll_log != null) { 421 progress_pane.remove(scroll_log); 422 } 423 process_log = new JTextArea(); 424 scroll_log = new JScrollPane(process_log); 425 progress_pane.add(scroll_log, BorderLayout.CENTER); 426 426 // clear the log list and message_log 427 427 options_pane.resetLogList(); 428 428 // Change the view. 429 430 429 processing = true; 430 card_layout.show(main_pane, PROGRESS); 431 431 // Reset the stop flag in all the process monitors, just incase. 432 433 434 432 ((GBuildProgressMonitor)build_monitor).reset(); 433 copy_monitor.setStop(false); 434 import_monitor.setStop(false); 435 435 // Set removeold automatically. 436 437 438 436 if(Gatherer.c_man.ready() && !Gatherer.c_man.built()) { 437 Gatherer.c_man.getCollection().build_options.setImportValue("removeold", true, null); 438 } 439 439 // Call CollectionManagers method to build collection. 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 440 Gatherer.c_man.importCollection(); 441 } 442 } 443 /** This class serves as the listener for actions on the cancel button. */ 444 private class CancelButtonListener 445 implements ActionListener { 446 /** This method attempts to cancel the current GShell task. It does this by first telling CollectionManager not to carry out any further action. This it turn tells the GShell to break from the current job immediately, without waiting for the processEnded message, and then kills the thread in an attempt to stop the process. The results of such an action are debatable. 447 * @param event An <strong>ActionEvent</strong> who, thanks to the power of object oriented programming, we don't give two hoots about. 448 * @see org.greenstone.gatherer.Gatherer 449 * @see org.greenstone.gatherer.collection.CollectionManager 450 * @see org.greenstone.gatherer.gui.BuildOptions 451 * @see org.greenstone.gatherer.shell.GShellProgressMonitor 452 */ 453 public void actionPerformed(ActionEvent event) { 454 build_button.setEnabled(true); 455 cancel_button.setEnabled(false); 456 processing = false; 457 options_pane.addNewLog(OptionsPane.CANCELLED); 458 card_layout.show(main_pane, CONTROL); 459 459 // Set the stop flag in all the process monitor. 460 461 462 460 build_monitor.setStop(true); 461 copy_monitor.setStop(true); 462 import_monitor.setStop(true); 463 463 // Set removeold automatically. 464 465 466 464 if(Gatherer.c_man.ready()) { // and it should be. 465 Gatherer.c_man.getCollection().build_options.setImportValue("removeold", true, null); 466 } 467 467 // Remove the collection lock. 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 468 Gatherer.g_man.lockCollection(false, false); 469 } 470 } 471 /** The OptionTree is simply a tree structure that has a root node labelled "Options" and then has a child node for each available options screen. These screens are either combinations of the available import and build arguments, or a message log detailing the shell processes progress. */ 472 private class OptionTree 473 extends JTree 474 implements TreeSelectionListener { 475 /** The model behind the tree. */ 476 private DefaultTreeModel model = null; 477 /** The previous options view displayed, which is sometimes needed to refresh properly. */ 478 private JPanel previous_pane = null; 479 /** The node corresponding to the building options view. */ 480 private OptionTreeNode building = null; 481 /** The node corresponding to the importing options view. */ 482 private OptionTreeNode importing = null; 483 /** The node corresponding to the log view. */ 484 private OptionTreeNode log = null; 485 /** The root node of the options tree, which has no associated options view. */ 486 private OptionTreeNode options = null; 487 /** Constructor. 488 * @see org.greenstone.gatherer.gui.CreatePane.OptionTreeNode 489 */ 490 public OptionTree() { 491 super(); 492 addTreeSelectionListener(this); 493 getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 494 setRootVisible(false); 495 setToggleClickCount(1); 496 496 // Create tree. 497 498 499 500 497 building = new OptionTreeNode(get("Build")); 498 importing = new OptionTreeNode(get("Import")); 499 log = new OptionTreeNode(get("Log")); 500 options = new OptionTreeNode(get("Options")); 501 501 502 503 504 505 506 502 model = new DefaultTreeModel(options); 503 setModel(model); 504 model.insertNodeInto(importing, options, 0); 505 model.insertNodeInto(building, options, 1); 506 model.insertNodeInto(log, options, 2); 507 507 // Expand the root node 508 509 510 508 expandPath(new TreePath(options)); 509 } 510 /** Any implementation of TreeSelectionListener must include this method to allow this listener to know when the selection has changed. Here we swap the options view depending on the selected OptionTreeNode. 511 511 * @param event A <Strong>TreeSelectionEvent</strong> which contains all the information garnered when the event occured. 512 512 * @see org.greenstone.gatherer.gui.CreatePane.OptionTreeNode 513 513 */ 514 515 516 514 public void valueChanged(TreeSelectionEvent event) { 515 TreePath path = null; 516 OptionTreeNode node = null; 517 517 //if(event != null) { 518 519 520 521 522 518 //path = event.getPath(); 519 path = getSelectionPath(); 520 if(path != null) { 521 node = (OptionTreeNode)path.getLastPathComponent(); 522 } 523 523 //} 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 524 if(previous_pane != null) { 525 //target_pane.remove(previous_pane); 526 options_pane.update(previous_pane); 527 if(scroll_pane != null) { 528 right.remove(scroll_pane); 529 } 530 else { 531 right.remove(previous_pane); 532 } 533 previous_pane = null; 534 scroll_pane = null; 535 } 536 if(node != null && node.equals(building)) { 537 previous_pane = options_pane.buildBuild(); 538 scroll_pane = new JScrollPane(previous_pane); 539 right.add(scroll_pane, BorderLayout.CENTER); 540 //target_pane.add(previous_pane, BorderLayout.CENTER); 541 } 542 else if(node != null && node.equals(importing)) { 543 previous_pane = options_pane.buildImport(); 544 scroll_pane = new JScrollPane(previous_pane); 545 right.add(scroll_pane, BorderLayout.CENTER); 546 //target_pane.add(previous_pane, BorderLayout.CENTER); 547 } 548 else { 549 previous_pane = options_pane.buildLog(); 550 right.add(previous_pane, BorderLayout.CENTER); 551 right.updateUI(); // we need to repaint the log pane, cos it hasn't changed since last time 552 ///ystem.err.println("I've added the log back to the right pane again."); 553 //target_pane.add(previous_pane, BorderLayout.CENTER); 554 } 555 555 //scroll_pane.setViewportView(previous_pane); 556 557 558 559 560 */ 561 562 563 564 565 566 567 556 previous_pane.validate(); 557 } 558 } 559 /** The <strong>OptionTree</strong> is built from these nodes, each of which has several methods used in creating the option panes. 560 */ 561 private class OptionTreeNode 562 extends DefaultMutableTreeNode 563 implements Comparable { 564 /** The text label given to this node in the tree. */ 565 private String title = null; 566 /** Constructor. 567 * @param title The <strong>String</strong> which serves as this nodes title. 568 568 */ 569 570 571 572 573 569 public OptionTreeNode(String title) { 570 super(); 571 this.title = title; 572 } 573 /** This method compares two nodes for ordering. 574 574 * @param obj The <strong>Object</strong> to compare to. 575 575 * @return An <strong>int</strong> of one of the possible values -1, 0 or 1 indicating if this node is less than, equal to or greater than the target node respectively. 576 576 */ 577 578 579 580 577 public int compareTo(Object obj) { 578 return title.compareTo(obj.toString()); 579 } 580 /** This method checks if two nodes are equivelent. 581 581 * @param obj The <strong>Object</strong> to be tested against. 582 582 * @return A <strong>boolean</strong> which is <i>true</i> if the objects are equal, <i>false</i> otherwise. 583 583 */ 584 585 586 587 588 589 590 584 public boolean equals(Object obj) { 585 if(compareTo(obj) == 0) { 586 return true; 587 } 588 return false; 589 } 590 /** Method to translate this node into a textual representation. 591 591 * @return A <strong>String</strong> which in this case is the title. 592 592 */ 593 594 595 596 593 public String toString() { 594 return title; 595 } 596 } 597 597 } -
trunk/gli/src/org/greenstone/gatherer/gui/EditorDialog.java
r4293 r4367 45 45 */ 46 46 final public class EditorDialog 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 47 extends JDialog 48 implements ActionListener { 49 /** The cancel, and I don't want the text I've typed, button. */ 50 private JButton cancel = null; 51 /** The ok, I'll save what I've just typed in, button. */ 52 private JButton ok = null; 53 /** The area in which we type. */ 54 private JTextArea text = null; 55 /** And what result should be passed back to our caller. */ 56 private String result = null; 57 /** The size of the edit pop-up. */ 58 final static private Dimension SIZE = new Dimension(400,400); 59 /** Constructor.*/ 60 public EditorDialog() { 61 } 62 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we generate a pop-up window to edit in. 63 63 * @param event An <strong>ActionEvent</strong> containing information about the event. 64 64 */ 65 66 67 68 69 70 71 65 public void actionPerformed(ActionEvent event) { 66 if(event.getSource() == ok) { 67 result = text.getText(); 68 } 69 dispose(); 70 } 71 /** Method to display the editing box on screen. 72 72 * @param value The initial text to be displayed in the editing area, as a <strong>String</strong>. 73 73 * @return The new value for the metadata value as a <strong>String</strong> or <i>null</i> if the user has pressed cancel. 74 74 */ 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 75 public String display(String value) { 76 setModal(true); 77 setSize(SIZE); 78 setTitle(Gatherer.dictionary.get("General.Edit")); 79 // Create 80 cancel = new JButton(Gatherer.dictionary.get("General.Cancel")); 81 ok = new JButton(Gatherer.dictionary.get("General.OK")); 82 text = new JTextArea(value); 83 text.setCaretPosition(value.length()); 84 text.setEditable(true); 85 text.setLineWrap(true); 86 text.setWrapStyleWord(true); 87 // Listeners 88 cancel.addActionListener(this); 89 ok.addActionListener(this); 90 // Layout 91 JPanel button_pane = new JPanel(); 92 button_pane.setLayout(new GridLayout(1,2)); 93 button_pane.add(ok); 94 button_pane.add(cancel); 95 95 96 97 98 99 96 JPanel content_pane = (JPanel) getContentPane(); 97 content_pane.setLayout(new BorderLayout()); 98 content_pane.add(new JScrollPane(text), BorderLayout.CENTER); 99 content_pane.add(button_pane, BorderLayout.SOUTH); 100 100 101 102 103 104 105 101 Dimension screen_size = Gatherer.config.screen_size; 102 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 103 show(); 104 return result; 105 } 106 106 } -
trunk/gli/src/org/greenstone/gatherer/gui/FileAssociationDialog.java
r4293 r4367 51 51 */ 52 52 public class FileAssociationDialog 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 53 extends JDialog { 54 /** <i>true</i> iff this addition action been cancelled by the user. */ 55 private boolean cancelled = false; 56 /** <i>true</i> iff we should ignore any current changes to the extension list. */ 57 private boolean ignore = false; 58 /** <i>true</i> iff the extension has not changed recently, but the command has. */ 59 private boolean save_required = false; 60 /** A reference to ourselves so that our inner classes can dispose of us. */ 61 private FileAssociationDialog self; 62 /** A reference to the manager in charge of storing all the file association information. */ 63 private FileAssociationManager manager; 64 /** The button used to open a file browser for simplier executable selection. */ 65 private JButton browse; 66 /** The button used to cancel this dialog without commiting any changes. */ 67 private JButton cancel; 68 /** The button used to hide this dialog after updating or adding file associations as necessary. */ 69 private JButton ok; 70 /** The combobox used to select what extension you wish to change. */ 71 private GComboBox extension; 72 /** A field for entering the command string. */ 73 private JTextField command; 74 /** The extension last chosen from the combobox. This way we can determine if the extension has been modified by the user. */ 75 private String previous_extension; 76 /** The default size of a label. */ 77 static final private Dimension LABEL_SIZE = new Dimension(150, 25); 78 /** The default size for the dialog. */ 79 static final private Dimension SIZE = new Dimension(600, 150); 80 /** Create a new file association dialog. 81 * @param manager A reference to the <strong>FileAssociationManager</strong> so we can determine what extensions are already associated. 82 * @see org.greenstone.gatherer.Configuration 83 * @see org.greenstone.gatherer.gui.Coloring 84 */ 85 public FileAssociationDialog(FileAssociationManager manager) { 86 super(Gatherer.g_man); 87 this.manager = manager; 88 this.self = this; 89 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 90 // Creation 91 setModal(true); 92 setSize(SIZE); 93 setTitle(get("Title")); 94 JPanel content_pane = (JPanel) getContentPane(); 95 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false)); 96 JPanel extension_pane = new JPanel(); 97 extension_pane.setOpaque(false); 98 JLabel extension_label = new JLabel(get("Extension")); 99 extension_label.setPreferredSize(LABEL_SIZE); 100 extension = new GComboBox(); 101 extension.setEditable(true); 102 extension.setPreferredSize(LABEL_SIZE); 103 for(Iterator extensions = manager.keySet().iterator(); extensions.hasNext(); ) { 104 extension.add((String)extensions.next()); 105 } 106 JPanel command_pane = new JPanel(); 107 command_pane.setOpaque(false); 108 JLabel command_label = new JLabel(get("Command")); 109 command_label.setPreferredSize(LABEL_SIZE); 110 JPanel inner_pane = new JPanel(); 111 inner_pane.setOpaque(false); 112 command = new JTextField(); 113 command.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 114 command.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 115 command.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 116 if(extension.count() > 0) { 117 command.setText(manager.getCommandImmediately((String)extension.get(0))); 118 } 119 browse = new JButton(get("Browse")); 120 browse.setBackground(Gatherer.config.getColor("coloring.button_background", false)); 121 browse.setPreferredSize(LABEL_SIZE); 122 JPanel button_pane = new JPanel(); 123 button_pane.setOpaque(false); 124 ok = new JButton(get("General.OK")); 125 ok.setBackground(Gatherer.config.getColor("coloring.button_background", false)); 126 cancel = new JButton(get("General.Cancel")); 127 cancel.setBackground(Gatherer.config.getColor("coloring.button_background", false)); 128 // Connection 129 browse.addActionListener(new BrowseListener()); 130 cancel.addActionListener(new CancelListener()); 131 ok.addActionListener(new OKListener()); 132 extension.addItemListener(new ExtensionListener()); 133 command.addKeyListener(new CommandListener()); 134 // Layout 135 extension_pane.setLayout(new BorderLayout()); 136 extension_pane.add(extension_label, BorderLayout.WEST); 137 extension_pane.add(extension, BorderLayout.EAST); 138 139 inner_pane.setLayout(new BorderLayout()); 140 inner_pane.add(command, BorderLayout.CENTER); 141 inner_pane.add(browse, BorderLayout.EAST); 142 143 command_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0)); 144 command_pane.setLayout(new GridLayout(2,1)); 145 command_pane.add(command_label); 146 command_pane.add(inner_pane); 147 148 button_pane.setLayout(new GridLayout(1,2,2,2)); 149 button_pane.add(ok); 150 button_pane.add(cancel); 151 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 152 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 153 content_pane.setLayout(new BorderLayout()); 154 content_pane.add(extension_pane, BorderLayout.NORTH); 155 content_pane.add(command_pane, BorderLayout.CENTER); 156 content_pane.add(button_pane, BorderLayout.SOUTH); 157 158 Dimension screen_size = Gatherer.config.screen_size; 159 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 160 } 161 /** Destructor to ensure dialog gets garbage collected. */ 162 public void destroy() { 163 self = null; 164 manager = null; 165 browse = null; 166 cancel = null; 167 ok = null; 168 extension = null; 169 command = null; 170 previous_extension = null; 171 } 172 /** Redisplay the dialog, ensuring that the details (or lack thereof) for a certain extension is apparent. 173 173 * @param new_extension The extension code as a <strong>String</strong>. 174 174 */ 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 */ 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 */ 231 232 233 234 235 236 237 238 239 240 241 242 */ 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 */ 280 281 282 283 284 285 286 287 175 public String display(String new_extension) { 176 if(new_extension != null) { 177 int index = extension.add(new_extension); 178 extension.setSelectedIndex(index); 179 } 180 else { 181 182 } 183 show(); 184 if(save_required) { 185 manager.setCommand((String)extension.getSelectedItem(), (String)command.getText()); 186 save_required = false; 187 } 188 if(cancelled) { 189 return null; 190 } 191 return command.getText(); 192 } 193 194 private String get(String key) { 195 return get(key, null); 196 } 197 198 private String get(String key, String args[]) { 199 if(key.indexOf(".") == -1) { 200 key = "FileAssociationDialog." + key; 201 } 202 return Gatherer.dictionary.get(key, args); 203 } 204 205 /** Whenever the user clicks the browse button, we should open up a file browser to allow them to select an executable file from somewhere in the file system. */ 206 private class BrowseListener 207 implements ActionListener { 208 /** Open up a simple JFileChooser when the user clicks the button. 209 * @param event An <strong>ActionEvent</strong> containing information about the event. 210 */ 211 public void actionPerformed(ActionEvent event) { 212 JFileChooser chooser = new JFileChooser(new File(Utility.BASE_DIR)); 213 chooser.setDialogTitle(get("Browse_Title")); 214 chooser.setFileFilter(new ExtensionFileFilter(".bat", get("Batch_File"))); 215 chooser.setFileFilter(new ExtensionFileFilter(".com", get("Command_File"))); 216 chooser.setFileFilter(new ExtensionFileFilter(".exe", get("Executable_File"))); 217 chooser.setAcceptAllFileFilterUsed(true); 218 int return_val = chooser.showOpenDialog(null); 219 if(return_val == JFileChooser.APPROVE_OPTION) { 220 command.setText(chooser.getSelectedFile().getAbsolutePath()); 221 save_required = true; 222 } 223 } 224 } 225 /** Listens for actions apon the cancel button, and if detected disposes of the dialog without saving changes. */ 226 private class CancelListener 227 implements ActionListener { 228 /** Listens for actions apon the cancel button, and if detected disposes of the dialog without saving changes. 229 * @param event An <strong>ActionEvent</strong> containing further information about the action. 230 */ 231 public void actionPerformed(ActionEvent event) { 232 cancelled = true; 233 save_required = false; 234 self.dispose(); 235 } 236 } 237 /** If any changes occur to the command field, mark it as needing saving before we can change extensions, or dispose of this dialog (other than cancelling. */ 238 private class CommandListener 239 extends KeyAdapter { 240 /** Whenever we detect a new character has been typed, note that we need to update this association in the manager. 241 * @param event A <strong>KeyEvent</strong> containing information about the key typed event. 242 */ 243 public void keyTyped(KeyEvent event) { 244 save_required = true; 245 } 246 } 247 /** Whenever the user selects an extension, we should fill out the command field with whatever value has been previously entered for the command (if any). */ 248 private class ExtensionListener 249 implements ItemListener { 250 /** This method is called whenever the selection in the extension list changes, so that we can save any old details, then load up the information for the new selection. 251 * @param event An <strong>ItemEvent</strong> encompassing everything you ever wanted to know about the list selectio, but were afraid to ask. 252 * @see org.greenstone.gatherer.file.FileAssociationManager 253 */ 254 public void itemStateChanged(ItemEvent event) { 255 String ext = (String) extension.getSelectedItem(); 256 if(!ignore && ext != null && ext.length() > 0) { 257 ignore = true; 258 // Save the previous extension if necessary 259 if(save_required && previous_extension != null) { 260 manager.setCommand(previous_extension, command.getText()); 261 save_required = false; 262 } 263 previous_extension = manager.getCommandImmediately((String)extension.getSelectedItem()); 264 if(previous_extension != null) { 265 command.setText(previous_extension); 266 } 267 else { 268 command.setText(""); 269 } 270 ignore = false; 271 } 272 } 273 } 274 /** Listen for clicks on the ok button, and dispose when detected. */ 275 private class OKListener 276 implements ActionListener { 277 /** When a click on OK is detected, save the current information, then dispose. 278 * @param event An <strong>ActionEvent</strong> with details about the button press. 279 */ 280 public void actionPerformed(ActionEvent event) { 281 if(save_required) { 282 manager.setCommand(extension.getSelectedItem().toString(), command.getText()); 283 save_required = false; 284 } 285 self.dispose(); 286 } 287 } 288 288 } -
trunk/gli/src/org/greenstone/gatherer/gui/FileProgress.java
r4293 r4367 8 8 9 9 public class FileProgress 10 10 extends JPanel { 11 11 12 12 private LongProgressBar progress; 13 13 14 15 16 14 public FileProgress() { 15 super(); 16 // Initialization 17 17 18 19 20 18 // Creation 19 progress = new LongProgressBar(); 20 // Connection 21 21 22 23 24 25 22 // Layout 23 setLayout(new BorderLayout()); 24 add(progress, BorderLayout.CENTER); 25 } 26 26 27 28 29 27 public void addValue(int data_size) { 28 progress.addValue(data_size); 29 } 30 30 31 32 33 31 public void setIndeterminate(boolean state) { 32 progress.setIndeterminate(state); 33 } 34 34 35 36 37 35 public void setMaximum(long size) { 36 progress.setMaximum(size); 37 } 38 38 39 40 41 39 public void setString(String label) { 40 progress.setString(label); 41 } 42 42 43 44 45 43 public void setValue(int value) { 44 progress.setValue(value); 45 } 46 46 } -
trunk/gli/src/org/greenstone/gatherer/gui/Filter.java
r4293 r4367 51 51 */ 52 52 public class Filter 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 */ 77 78 79 80 53 extends JPanel { 54 /** The other filters in this run of filters, used to ensure they all show the same thing. */ 55 private ArrayList others = null; 56 /** Is this the filter filter of this run of filters created (later filters will share the same information). */ 57 private boolean first = true; 58 /** Prevent any changes we make in the class from causing events which we then process causing events... */ 59 private boolean ignore = false; 60 /** A reference to ourselves so inner classes can refer to us. */ 61 private Filter this_filter = null; 62 /** The check box to enabled/diable filter. */ 63 private JCheckBox checkbox = null; 64 /** The editable combobox where you either choose a predefined filter, or type a new pseudo-regular expression. */ 65 private GComboBox combobox = null; 66 /** The label shown on the filter controls. */ 67 private JLabel label = null; 68 /** A reference to the tree this filter is being applied to. */ 69 private DragTree tree = null; 70 /** The default size for the label. */ 71 static final private Dimension SIZE = new Dimension(100,25); 72 /** Preprogrammed default filters. */ 73 static final private String DEFAULTS[] = {"^.*\\.html?$", "^.*\\.xml$", "^.*\\.txt$", "(^.*\\.jpe?g$)|(^.*\\.png$)|(^.\\.gif$)"}; 74 /** Constructor. 75 * @param tree A reference to the <strong>JTree</strong> being affected. 76 */ 77 public Filter(DragTree tree) { 78 this(tree, null); 79 } 80 /** Constructor. 81 81 * @param tree A reference to the <strong>JTree</strong> being affected. 82 82 * @param others An <strong>ArrayList</strong> of the other Filters already in this run. 83 83 */ 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 84 public Filter(DragTree tree, ArrayList others) { 85 super(); 86 if(others == null) { 87 this.others = new ArrayList(); 88 } 89 else { 90 this.others = others; 91 } 92 this.others.add(this); 93 this.this_filter = this; 94 this.tree = tree; 95 // Create components. 96 combobox = new GComboBox(); 97 combobox.add(new Entry()); 98 for(int i = 0; i < DEFAULTS.length; i++) { 99 try { 100 Entry entry = new Entry(get((new Integer(i)).toString(), null), Pattern.compile(DEFAULTS[i])); 101 combobox.add(entry); 102 } 103 catch (Exception error) { 104 error.printStackTrace(); 105 } 106 } 107 combobox.setEditable(true); 108 label = new JLabel(get("Filter_Tree")); 109 label.setPreferredSize(SIZE); 110 // Add listeners. 111 combobox.addItemListener(new ComboBoxListener()); 112 // Layout. 113 label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5)); 114 114 115 116 117 118 119 120 115 setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 116 setLayout(new BorderLayout()); 117 add(label, BorderLayout.WEST); 118 add(combobox, BorderLayout.CENTER); 119 } 120 /** Retrieve the combobox associated with this filter. 121 121 * @return A <strong>GComboBox</strong>. 122 122 */ 123 124 125 123 public GComboBox getComboBox() { 124 return combobox; 125 } 126 126 127 127 /** Change the background color of the filter. 128 128 * @param color The new background <strong>Color</strong>. 129 129 */ 130 131 132 130 public void setBackground(Color color) { 131 super.setBackground(color); 132 } 133 133 134 134 /** Used to restore the filter state to enabled, the normal state during collection editing. 135 135 * @param state The new state for the filter. <i>true</i> for enabled, <i>false</i> otherwise. 136 136 */ 137 138 139 140 141 142 143 137 public void setEnabled(boolean state) { 138 ignore = true; 139 combobox.setEditable(state); 140 combobox.setEnabled(state); 141 ignore = false; 142 } 143 /** Set the combobox model for this filter. 144 144 * @param model The new <strong>ComboBoxModel</strong> to use. 145 145 */ 146 147 148 149 146 public void setComboBoxModel(ComboBoxModel model) { 147 combobox.setModel(model); 148 } 149 /** Ensure that a certain entry is selected from the combobox. 150 150 * @param selection The <strong>Entry</strong> that should be selected. 151 151 */ 152 153 154 155 156 157 152 public void setComboBoxSelection(Entry selection) { 153 ignore = true; 154 combobox.setSelectedItem(selection); 155 ignore = false; 156 } 157 /** Set to signify that this filter is the first in a new run of filters. 158 158 * @param first <i>true</i> if this is the first filter in a run, <i>false</i> if it will just be added to the current run. 159 159 */ 160 161 162 163 160 public void setFirst(boolean first) { 161 this.first = first; 162 } 163 /** Spawn produces a copy of this filter, which has new controls, but shares listeners wih this filter, and vice versa. Thus we can have two synchronized, but differing sets of controls. 164 164 * @param tree_spawn The <strong>JTree</strong> this filter will affect. 165 165 * @return A new <strong>Filter</strong> which is in the same run as this filter. 166 166 */ 167 168 169 170 171 172 173 174 167 public Filter spawn(DragTree tree_spawn) { 168 Filter filter = new Filter(tree_spawn, others); 169 filter.setFirst(false); // No spawned copies should generate error messages, but fail silently. 170 filter.setComboBoxModel(combobox.getModel()); 171 filter.setComboBoxSelection((Entry)combobox.getSelectedItem()); 172 return filter; 173 } 174 /** Retrieve a phrase from the dictionary. 175 175 * @param key The unique identification <strong>String</strong> of a phrase from the dictionary. 176 176 */ 177 178 179 180 177 private String get(String key) { 178 return get(key, null); 179 } 180 /** Retrieve a phrase from the dictionary, augmenting with the given text fragments 181 181 * @param key The unique identification <strong>String</strong> of a phrase from the dictionary. 182 182 * @param args A <strong>String[]</strong> of arguments to be used to fill out parameter fields in the phrase returned. … … 184 184 * @see org.greenstone.gatherer.Gatherer 185 185 */ 186 187 188 189 190 191 192 186 private String get(String key, String args[]) { 187 if(key.indexOf(".") == -1) { 188 key = "Filter." + key; 189 } 190 return Gatherer.dictionary.get(key, args); 191 } 192 /** Encode an expression in pseudo-regular expression into regular expression. 193 193 * @param raw The pseudo-regular expression <strong>String</strong> which includes several characters which differ in meaning from regular expression queries. 194 194 * @return A proper regular expression as a <strong>String</strong>. 195 195 */ 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 196 private String encode(String raw) { 197 StringBuffer working = new StringBuffer(); 198 for(int i = 0; i < raw.length(); i++) { 199 char c = raw.charAt(i); 200 switch(c) { 201 case '.': 202 working.append("\\."); 203 break; 204 case '*': 205 working.append(".*"); 206 break; 207 case '?': 208 working.append("."); 209 break; 210 default: 211 working.append(Character.toLowerCase(c)); 212 } 213 } 214 return working.toString(); 215 } 216 /** This method applies the given pattern to the tree registered as belonging to this filter.*/ 217 private void setFilter(Pattern pattern) { 218 // Show busy cursor. 219 Gatherer.g_man.wait(true); 220 FileSystemModel model = (FileSystemModel) tree.getModel(); 221 // Apply filter 222 if(pattern != null) { 223 model.setFilter(pattern.pattern()); 224 } 225 else { 226 model.setFilter(null); 227 } 228 // Ask tree to completely refresh 229 tree.refresh(null); 230 // Restore cursor 231 Gatherer.g_man.wait(false); 232 } 233 /** Listens for changes in the combobox as when one is detected attempts to compile a regular expression from whatever text was entered. If successful, or if the item chosen was a predefined filter, it then applies the filter to the target tree. */ 234 private class ComboBoxListener 235 implements ItemListener { 236 /** Called when a new item is selected from the filter combobox, we treat the new entry as a pseudo-regular expression, compile it and then apply it to the tree. 237 * @param event An <strong>ItemEvent</strong> containing more information about the change performed. 238 * @see org.greenstone.gatherer.gui.Filter.Entry 239 */ 240 public void itemStateChanged(ItemEvent event) { 241 if(!ignore) { 242 ignore = true; 243 if(event.getStateChange() == ItemEvent.SELECTED) { 244 try { 245 Object temp = combobox.getSelectedItem(); 246 Entry entry = null; 247 if(temp instanceof String) { 248 String temp_str = (String) temp; 249 ///ystem.err.println("Filter = " + temp_str); 250 // Ignore any string which matches a predefined filter, starting with All Files. 251 if(temp_str.equals(get("All_Files"))) { 252 } 253 // HTM & HTML 254 else if(temp_str.equals(get("0"))) { 255 } 256 // XML 257 else if(temp_str.equals(get("1"))) { 258 } 259 // Text files 260 else if(temp_str.equals(get("2"))) { 261 } 262 // Images 263 else if(temp_str.equals(get("3"))) { 264 } 265 else { 266 entry = new Entry((String)temp, Pattern.compile(encode((String)temp))); 267 //combobox.removeItem(temp); 268 //int position = combobox.add(entry); 269 //combobox.setSelectedIndex(position); 270 } 271 } 272 else { 273 entry = (Entry) temp; 274 } 275 if(entry != null) { 276 setFilter(entry.getPattern()); 277 // Synchronize other controls. 278 /* 279 for(int i = 0; i < others.size(); i++) { 280 Filter sibling = (Filter) others.get(i); 281 if(sibling != this_filter) { 282 sibling.setComboBoxSelection((Entry)entry); 283 } 284 } 285 */ 286 } 287 // Else we ignore this event as being one of the painfully erroneous events we receive because we've been silly enough to have an editable combobox. 288 } 289 catch (PatternSyntaxException error) { 290 if(first) { 291 JOptionPane.showMessageDialog(Gatherer.g_man, get("Invalid_Pattern"), get("General.Error"), JOptionPane.ERROR_MESSAGE); 292 } 293 } 294 } 295 ignore = false; 296 } 297 } 298 } 299 /** An object that holds a filter entry. This is string used for the filter pattern and, if not custom built, its name. */ 300 private class Entry 301 implements Comparable { 302 /** The compiled pattern created from a regular expression. */ 303 private Pattern pattern = null; 304 /** The name of this filter entry. */ 305 private String name = null; 306 /** Constructor. */ 307 public Entry() { 308 } 309 /** Constructor. 310 310 * @param name The name of this entry as a <strong>String</strong>. 311 311 * @param pattern The compiled regular expression as a <strong>Pattern</strong>. 312 312 */ 313 314 315 316 317 313 public Entry(String name, Pattern pattern) { 314 this.name = name; 315 this.pattern = pattern; 316 } 317 /** Compare two Entrys for ordering. 318 318 * @param object The other Entry to compare to, as an <strong>Object</strong>. 319 319 * @return An <i>int</i> indicating the respective ordering, as defined in java.lang.String#compareTo 320 320 */ 321 322 323 324 321 public int compareTo(Object object) { 322 return toString().compareTo(object.toString()); 323 } 324 /** Retrieve the pattern associated with this entry. 325 325 * @return The <strong>Pattern</strong>. 326 326 */ 327 328 329 330 327 public Pattern getPattern() { 328 return pattern; 329 } 330 /** Translate this entry into a textual representation. 331 331 * @return A <strong>String</strong> containing the representation. 332 332 */ 333 334 335 336 337 338 339 340 341 342 343 344 345 346 333 public String toString() { 334 String result = null; 335 if(name != null) { 336 result = name; 337 } 338 else if(pattern == null) { 339 result = get("All_Files"); 340 } 341 else { 342 result = pattern.pattern(); 343 } 344 return result; 345 } 346 } 347 347 } -
trunk/gli/src/org/greenstone/gatherer/gui/GComboBox.java
r4293 r4367 47 47 */ 48 48 public class GComboBox 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 49 extends JComboBox { 50 51 private Color background = null; 52 private Color foreground = null; 53 private Color selection_background = null; 54 private Color selection_foreground = null; 55 56 private Model model; 57 58 public GComboBox() { 59 super(); 60 init(); 61 } 62 63 public GComboBox(Gatherer gatherer) { 64 this(); 65 } 66 67 public GComboBox(ArrayList data) { 68 super(data.toArray()); 69 init(); 70 } 71 72 public GComboBox(ComboBoxModel model) { 73 super(model); 74 init(); 75 } 76 77 public GComboBox(Object data[]) { 78 super(data); 79 init(); 80 } 81 82 public GComboBox(Vector data) { 83 super(data); 84 init(); 85 } 86 87 public int add(Object object) { 88 return model.add(object); 89 } 90 91 public Object get(int index) { 92 return model.getElementAt(index); 93 } 94 95 public int getMaximumRowCount() { 96 int size = model.getSize(); 97 if(size == 0) { 98 return 1; 99 } 100 else if(size < maximumRowCount) { 101 return model.getSize(); 102 } 103 return maximumRowCount; 104 } 105 106 public void clear() { 107 model.clear(); 108 } 109 110 public int count() { 111 return model.getSize(); 112 } 113 114 public void setBackgroundNonSelectionColor(Color background) { 115 this.background = background; 116 setEditor(new Editor()); 117 setRenderer(new Renderer()); 118 } 119 120 public void setTextNonSelectionColor(Color foreground) { 121 this.foreground = foreground; 122 setEditor(new Editor()); 123 setRenderer(new Renderer()); 124 } 125 126 public void setBackgroundSelectionColor(Color selection_background) { 127 this.selection_background = selection_background; 128 setEditor(new Editor()); 129 setRenderer(new Renderer()); 130 } 131 132 public void setTextSelectionColor(Color selection_foreground) { 133 this.selection_foreground = selection_foreground; 134 setEditor(new Editor()); 135 setRenderer(new Renderer()); 136 } 137 138 public void init() { 139 this.model = new Model(); 140 ComboBoxModel old_model = (ComboBoxModel) getModel(); 141 setModel(model); 142 // Restore any data given into our model 143 for(int i = 0; i < old_model.getSize(); i++) { 144 model.add(old_model.getElementAt(i)); 145 } 146 // Change component 147 UI ui = new UI(); 148 setUI(ui); 149 ui.setBackground(Color.white); 150 // Initialization 151 this.background = Gatherer.config.getColor("coloring.collection_tree_background", false); 152 this.foreground = Gatherer.config.getColor("coloring.collection_tree_foreground", false); 153 this.selection_background = Gatherer.config.getColor("coloring.collection_selection_background", false); 154 this.selection_foreground = Gatherer.config.getColor("coloring.collection_selection_foreground", false); 155 setEditor(new Editor()); 156 setRenderer(new Renderer()); 157 } 158 159 private class Editor 160 extends JTextField 161 implements ComboBoxEditor { 162 public Editor() { 163 setBackground(background); 164 setForeground(foreground); 165 setSelectionColor(selection_background); 166 setSelectedTextColor(selection_foreground); 167 } 168 169 public Component getEditorComponent() { 170 return this; 171 } 172 173 public Object getItem() { 174 return getText(); 175 } 176 177 public void setItem(Object item) { 178 if(item != null) { 179 setText(item.toString()); 180 } 181 else { 182 setText(""); 183 } 184 } 185 } 186 187 private class Model 188 extends DefaultComboBoxModel { 189 190 public int add(Object extension) { 191 int position = 0; 192 String extension_str = extension.toString().toLowerCase(); 193 while(extension != null && position < size()) { 194 String sibling = getElementAt(position).toString().toLowerCase(); 195 int order = extension_str.compareTo(sibling); 196 // If we are now less than the sibling, insert here. 197 if(order < 0) { 198 insertElementAt(extension, position); 199 extension = null; 200 } 201 // We are equal to the sibling, thus we already exist in list. Done. 202 else if(order == 0) { 203 extension = null; 204 } 205 // Continue searching. 206 else { 207 position++; 208 } 209 } 210 if(extension != null) { 211 position = size(); 212 addElement(extension); 213 } 214 return position; 215 } 216 217 public void clear() { 218 removeAllElements(); 219 } 220 221 public int size() { 222 return getSize(); 223 } 224 } 225 226 private class Renderer 227 extends JLabel 228 implements ListCellRenderer { 229 public Renderer() { 230 } 231 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 232 if(value != null) { 233 setText(value.toString()); 234 } 235 else { 236 setText(""); 237 } 238 setBackground(isSelected ? selection_background : background); 239 setForeground(isSelected ? selection_foreground : foreground); 240 setOpaque(true); 241 return this; 242 } 243 } 244 245 private class UI 246 extends BasicComboBoxUI { 247 public UI() { 248 super(); 249 } 250 251 protected ComboPopup createPopup() { 252 BasicComboPopup popup = new BasicComboPopup( comboBox ) { 253 public void show() { 254 if(comboBox.getMaximumRowCount() > 0) { 255 Dimension popupSize = new Dimension( comboBox.getWidth(), getPopupHeightForRowCount( comboBox.getMaximumRowCount())); 256 Rectangle popupBounds = new Rectangle( 0, 0, popupSize.width, popupSize.height); 257 scroller.setMaximumSize( popupBounds.getSize() ); 258 scroller.setPreferredSize( popupBounds.getSize() ); 259 scroller.setMinimumSize( popupBounds.getSize() ); 260 list.invalidate(); 261 int selectedIndex = comboBox.getSelectedIndex(); 262 if ( selectedIndex == -1 ) { 263 list.clearSelection(); 264 } 265 else { 266 list.setSelectedIndex( selectedIndex ); 267 } 268 list.ensureIndexIsVisible( list.getSelectedIndex() ); 269 setLightWeightPopupEnabled( comboBox.isLightWeightPopupEnabled() ); 270 show(arrowButton, arrowButton.getSize().width - (popupSize.width + 4), arrowButton.getSize().height); 271 } 272 } 273 }; 274 popup.getAccessibleContext().setAccessibleParent(comboBox); 275 return popup; 276 } 277 278 public void setBackground(Color background) { 279 arrowButton.setBackground(background); 280 } 281 } 282 282 } 283 -
trunk/gli/src/org/greenstone/gatherer/gui/GConfigPane.java
r4293 r4367 50 50 */ 51 51 public class GConfigPane 52 53 54 55 56 57 58 52 extends JPanel { 53 /** The collection manager is responsible for parsing in, and allowing the editing of, a single collections configuration file. */ 54 private CollectionDesignManager cdm = null; 55 /** The constructor. */ 56 public GConfigPane() { 57 } 58 /** This method is called whenever the state of the current collection 59 59 * changes. 60 60 * @param ready <i>true</i> if a collection is loaded and ready, <i>false</i> otherwise. 61 61 */ 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 62 public void collectionChanged(boolean ready) { 63 ///atherer.println("CollectionChanged(" + ready + ")"); 64 if(ready) { 65 String filename = Gatherer.c_man.getCollectionConfig(); 66 if(cdm != null && cdm.getFilename().equals(filename)) { 67 return; 68 } 69 else { 70 if(cdm != null) { 71 cdm.destroy(); 72 cdm = null; 73 } 74 // Create a new config manager. 75 cdm = new CollectionDesignManager(); 76 // Parse the configuration file. 77 cdm.parse(filename); 78 // Display it. 79 cdm.display(this); 80 } 81 } 82 else { 83 if(cdm != null) { 84 cdm.destroy(); 85 cdm = null; 86 } 87 } 88 } 89 /** Called to cause the components to lay themselves out and be displayed. 90 90 */ 91 92 93 94 95 96 97 98 99 100 91 public void display() { 92 // Layout 93 this.setLayout(new BorderLayout()); 94 } 95 public void gainFocus() { 96 cdm.gainFocus(); 97 } 98 public ArrayList getIndexes() { 99 return cdm.getIndexes(); 100 } 101 101 102 103 104 102 public ArrayList getLanguageCodes() { 103 return cdm.languages.getLanguageCodes(); 104 } 105 105 106 107 108 109 110 111 112 113 106 public Rectangle setSelectedElement(ElementWrapper element) { 107 return cdm.setSelectedElement(element.getName()); 108 } 109 public void saveConfiguration() { 110 if(cdm != null) { 111 cdm.save(); 112 } 113 } 114 114 } -
trunk/gli/src/org/greenstone/gatherer/gui/GEditorPane.java
r4293 r4367 66 66 */ 67 67 public class GEditorPane 68 69 70 71 68 extends JEditorPane 69 implements ActionListener, FocusListener, UndoableEditListener { 70 71 private boolean focusable = true; 72 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 73 private File file = null; 74 75 private Gatherer gatherer = null; 76 77 private JButton redo_button = null; 78 private JButton undo_button = null; 79 80 private JEditorPane editor = null; 81 82 private UndoManager undo = null; 83 84 /** This constructor simply sets whether this pane is focusable. 85 * @param focusable A Boolean indicating whether this component should 86 * be focusable. 87 */ 88 public GEditorPane(boolean focusable) { 89 this.focusable = focusable; 90 } 91 92 /** This constructor sets up the initial JEditorPane settings, and 93 * creates the necessary classes to support undo actions. 94 * @param gatherer A reference to Gatherer for purposes of messaging 95 * and dictionary. 96 */ 97 public GEditorPane(Gatherer gatherer) { 98 this.gatherer = gatherer; 99 //this.setContentType("text/html"); 100 this.setEnabled(true); 101 this.setFont(new Font("Courier New", Font.PLAIN, 12)); 102 // Undo support. 103 undo = new UndoManager(); 104 // Create components. 105 redo_button = new JButton(gatherer.dictionary.get("UndoManager.Redo")); 106 redo_button.addActionListener(this); 107 redo_button.setEnabled(false); 108 undo_button = new JButton(gatherer.dictionary.get("UndoManager.Undo")); 109 undo_button.addActionListener(this); 110 undo_button.setEnabled(false); 111 } 112 113 /** This initially calls GEditorPane(focusable), but then uses 114 * the given file to find the initial content of this pane. Moreover 115 * it will now respond to loss of focus events by saving the document 116 * content to this file. 117 * this pane is focusable. 118 * @param file A File to be used as a data source/destination. 119 * @param focusable A Boolean indicating whether this component should 120 * be focusable. 121 */ 122 public GEditorPane(File file, boolean focusable) { 123 this(focusable); 124 loadFile(file); 125 this.addFocusListener(this); 126 } 127 128 /** This initially calls GEditorPane(gatherer), but then sets whether 129 * this pane is focusable. 130 * @param gatherer A reference to Gatherer for purposes of messaging 131 * and dictionary. 132 * @param focusable A Boolean indicating whether this component should 133 * be focusable. 134 */ 135 public GEditorPane(Gatherer gatherer, boolean focusable) { 136 this(gatherer); 137 this.focusable = focusable; 138 } 139 140 /** This initially calls GEditorPane(focusable), but then sets 141 * the initial content for this panel. 142 * this pane is focusable. 143 * @param content A String indicating the initial content of this pane. 144 * @param focusable A Boolean indicating whether this component should 145 * be focusable. 146 */ 147 public GEditorPane(String content, boolean focusable) { 148 this(focusable); 149 this.setText(content); 150 } 151 152 /** This initially calls GEditorPane(gatherer, focusable), but then sets 153 * the initial content for this panel. 154 * this pane is focusable. 155 * @param gatherer A reference to Gatherer for purposes of messaging 156 * and dictionary. 157 * @param content A String indicating the initial content of this pane. 158 * @param focusable A Boolean indicating whether this component should 159 * be focusable. 160 */ 161 public GEditorPane(Gatherer gatherer, String content, boolean focusable) { 162 this(gatherer, focusable); 163 this.setText(content); 164 } 165 166 /** This initially calls GEditorPane(gatherer, focusable), but then uses 167 * the given file to find the initial content of this pane. Moreover 168 * it will now respond to loss of focus events by saving the document 169 * content to this file. 170 * this pane is focusable. 171 * @param gatherer A reference to Gatherer for purposes of messaging 172 * and dictionary. 173 * @param file A File to be used as a data source/destination. 174 * @param focusable A Boolean indicating whether this component should 175 * be focusable. 176 */ 177 public GEditorPane(Gatherer gatherer, File file, boolean focusable) { 178 this(gatherer, focusable); 179 loadFile(file); 180 this.addFocusListener(this); 181 } 182 183 /** Any implementation of ActionListener must include this method so we 184 * can be informed whenever an action has occured. 185 * @param event An ActionEvent. 186 */ 187 public void actionPerformed(ActionEvent event) { 188 try { 189 if(event.getSource() == redo_button) { 190 undo.redo(); 191 } 192 else { 193 undo.undo(); 194 } 195 } 196 catch (CannotRedoException error) { 197 error.printStackTrace(); 198 } 199 catch (CannotUndoException error) { 200 error.printStackTrace(); 201 } 202 // Update controls to reflect change. 203 redo_button.setEnabled(undo.canRedo()); 204 undo_button.setEnabled(undo.canUndo()); 205 } 206 207 /** Any implementation of FocusListener must include this method so we 208 * can be notified when focus is gained. 209 * @param event A FocusEvent. 210 */ 211 public void focusGained(FocusEvent event) { 212 } 213 214 /** Any implementation of FocusListener must include this method so we 215 * can be notified when focus is lost. 216 * @param event A FocusEvent. 217 */ 218 public void focusLost(FocusEvent event) { 219 if(file != null) { 220 220 // Save the document to file. 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 221 try { 222 FileOutputStream out = new FileOutputStream(file); 223 out.write(this.getText().getBytes()); 224 out.close(); 225 } 226 catch (Exception error) { 227 error.printStackTrace(); 228 } 229 } 230 } 231 232 /** Retrieves the redo button for this edit pane. 233 * @return A JButton. 234 */ 235 public JButton getRedoButton() { 236 return redo_button; 237 } 238 239 /** Retrieves the undo button for this edit pane. 240 * @return A JButton. 241 */ 242 public JButton getUndoButton() { 243 return undo_button; 244 } 245 246 /** This method is called by any window manager to determine if this 247 * particular component is focusable. 248 * @return A Boolean specifying if this component is focus traversable. 249 * @deprecated 250 */ 251 /** public boolean isFocusTraversable() { 252 return focusable; 253 } 254 */ 255 256 /** Loads the contents of the specified file into the document. 257 * @param file The target File. 258 */ 259 259 public void loadFile(File file) { 260 260 // Load the file. … … 266 266 while((character = in.read()) != -1) { 267 267 content = content + (char)character; 268 268 } 269 269 in.close(); 270 270 this.file = file; … … 277 277 } 278 278 279 280 281 282 283 284 285 279 /** Any implementation of Undoable must include this method so we can 280 * be informed when an undoable event has occured. 281 * @param event An UndoableEditEvent. 282 */ 283 public void undoableEditHappened(UndoableEditEvent event) { 284 if(undo != null) { 285 undo.addEdit(event.getEdit()); 286 286 // Update controls to reflect change. 287 288 289 290 287 redo_button.setEnabled(undo.canRedo()); 288 undo_button.setEnabled(undo.canUndo()); 289 } 290 } 291 291 } -
trunk/gli/src/org/greenstone/gatherer/gui/GProgressBar.java
r4293 r4367 65 65 66 66 public class GProgressBar 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 67 extends JPanel 68 implements ActionListener { 69 70 private boolean simple = false; 71 72 private Dimension bar_size = new Dimension(520, 15); 73 74 private Gatherer gatherer; 75 76 private ImageIcon busy_bar; 77 private ImageIcon ready_bar; 78 79 private int current_action; 80 private int err_count; 81 private int file_count; 82 private int total_count; 83 83 private int warning_count; 84 84 85 86 85 private JLabel current_status; 86 private JLabel main_status; 87 87 private JLabel results_status; 88 88 private JLabel status; 89 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 90 private JPanel center_pane; 91 private JPanel inner_pane; 92 93 private JProgressBar progress; 94 95 private long file_size; 96 private long total_size; 97 98 private String current_url; 99 private String initial_url; 100 101 private Job owner; 102 103 public JButton action; 104 public JButton cancel; 105 106 //public GProgressBar(Gatherer gatherer, WGet owner, String initial_url) { 107 // this.gatherer = gatherer; 108 public GProgressBar(Job owner, String initial_url, boolean simple) { 109 this.owner = owner; 110 this.current_url = null; 111 this.err_count = 0; 112 this.initial_url = initial_url; 113 this.file_count = 0; 114 this.file_size = 0; 115 this.simple = simple; 116 this.total_count = 0; 117 this.total_size = 0; 118 this.warning_count = 0; 119 120 this.setLayout(new BorderLayout()); 121 this.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); 122 //this.setMinimumSize(Utility.PROGRESS_BAR_SIZE); 123 //this.setSize(Utility.PROGRESS_BAR_SIZE); 124 //this.setMaximumSize(Utility.PROGRESS_BAR_SIZE); 125 //this.setAlignmentY(Component.LEFT_ALIGNMENT); 126 //this.setHorizontalAlignment(JLabel.LEFT); 127 128 this.current_action = Job.STOPPED; 129 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 130 inner_pane = new JPanel(new BorderLayout()); 131 inner_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 132 133 action = new JButton(Utility.getImage("vcrplay.gif")); 134 //action.setToolTipText(get("Action_Tip")); 135 action.setToolTipText("Start current download"); 136 action.addActionListener(this); 137 action.addActionListener(owner); 138 139 center_pane = new JPanel(new GridLayout(3,1)); 140 141 main_status = new JLabel(); 142 143 current_status = new JLabel(); 144 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 145 results_status = new JLabel(); 146 147 progress = new JProgressBar(); 148 progress.setString("Waiting to start"); 149 progress.setStringPainted(true); 150 progress.setMinimum(0); 151 progress.setMaximum(0); 152 progress.setEnabled(false); 153 inner_pane.add(progress, BorderLayout.CENTER); 154 155 center_pane.add(main_status); 156 center_pane.add(current_status); 157 center_pane.add(results_status); 158 159 cancel = new JButton(Utility.getImage("vcrstop.gif")); 160 //cancel.setToolTipText(get("Cancel_Tip")); 161 cancel.setToolTipText("Cancel current download"); 162 cancel.addActionListener(owner); 163 cancel.addActionListener(this); 164 165 inner_pane.add(center_pane, BorderLayout.NORTH); 166 167 this.add(action, BorderLayout.WEST); 168 this.add(inner_pane, BorderLayout.CENTER); 169 this.add(cancel, BorderLayout.EAST); 170 171 // Make the labels, etc update. 172 refresh(); 173 } 174 175 public void actionPerformed(ActionEvent event) { 176 if(event.getSource() == action) { 177 if(current_action == Job.RUNNING) { 178 current_action = Job.STOPPED; 179 action.setIcon(Utility.getImage("vcrplay.gif")); 180 action.setToolTipText("Start current download"); 181 cancel.setEnabled(true); 182 } 183 else { 184 current_action = Job.RUNNING; 185 action.setIcon(Utility.getImage("vcrpause.gif")); 186 action.setToolTipText("Pause current download"); 187 cancel.setEnabled(false); 188 } 189 } 190 } 191 192 /** This method is called when a new download is begun. The 193 * details of the download are updated and a new JProgressBar 194 * assigned to track the download. 195 * @param url The url String of the file that is being downloaded. 196 * @param size The size of the file as an Int. 197 */ 198 public void addDownload(String url) { 199 current_url = url; 200 file_size = 0; 201 refresh(); 202 } 203 204 /** When the download of the current url is completed, this method 205 * is called to enlighten the GProgressBar of this fact. 206 */ 207 public void downloadComplete() { 208 current_url = null; 209 file_count++; 210 if(total_count < (file_count + err_count + warning_count)) { 211 total_count = (file_count + err_count + warning_count); 212 } 213 progress.setValue(progress.getMaximum()); 214 progress.setString("Download Complete."); 215 refresh(); 216 } 217 218 public void downloadFailed() { 219 err_count++; 220 if(total_count < (file_count + err_count + warning_count)) { 221 total_count = (file_count + err_count + warning_count); 222 } 223 refresh(); 224 } 225 225 226 226 public void downloadWarning() { 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 227 warning_count++; 228 if(total_count < (file_count + err_count + warning_count)) { 229 total_count = (file_count + err_count + warning_count); 230 } 231 refresh(); 232 } 233 234 public Dimension getPerferredSize() { 235 return Utility.PROGRESS_BAR_SIZE; 236 } 237 238 /** When a link to be downloaded is located, the increaseTotalCount 239 * method is called. In this way the total count shows the most 240 * accurate remaining number of files to be downloaded. 241 */ 242 public void increaseFileCount() { 243 total_count++; 244 refresh(); 245 } 246 247 /** When a mirroring task is first initiated this function is called 248 * to set initial values for the variables if necessary and to 249 * fiddle visual components such as the tool tip etc. 250 * @param reset A Boolean specifying whether the variables should be 251 * reset to zero. 252 */ 253 public void mirrorBegun(boolean reset) { 254 if(reset) { 255 this.file_count = 0; 256 this.file_size = 0; 257 this.total_count = 0; 258 this.total_size = 0; 259 this.err_count = 0; 260 this.warning_count = 0; 261 } 262 current_action = Job.RUNNING; 263 action.setIcon(Utility.getImage("vcrpause.gif")); 264 action.setToolTipText("Pause current download"); 265 cancel.setEnabled(false); 266 if(simple) { 267 progress.setIndeterminate(true); 268 } 269 } 270 271 /** Once a mirroring task is complete, is the Job returns from the 272 * native call but the status is still running, then this method 273 * is called to once again tinker with the pritty visual 274 * components. 275 */ 276 public void mirrorComplete() { 277 current_action = Job.COMPLETE; 278 current_url = null; 279 if(simple) { 280 progress.setIndeterminate(false); 281 } 282 progress.setValue(progress.getMaximum()); 283 progress.setString("Mirroring Complete."); 284 285 action.setIcon(Utility.getImage("vcrfastforward.gif")); 286 action.setToolTipText("Restart current download"); 287 cancel.setEnabled(true); 288 this.updateUI(); 289 } 290 291 /** When called this method updates the GProgressBar to reflect 292 * the ammount of the current file downloaded. 293 */ 294 public void updateProgress(long current, long expected) { 295 file_size = file_size + current; 296 if(!progress.isIndeterminate()) { 297 297 // If current is zero, then this is the 'precall' before the 298 298 // downloading actually starts. 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 299 if(current == 0) { 300 // Remove the old progress bar, then deallocate it. 301 inner_pane.remove(progress); 302 progress = null; 303 if(expected == 0) { 304 // We don't have a content length. This bar will go from 305 // 0 to 100 only! 306 progress = new JProgressBar(0, 100); 307 } 308 else { 309 // Assign a new progress bar of length expected content 310 // length. 311 progress = 312 new JProgressBar(0, (new Long(expected)).intValue()); 313 } 314 progress.setEnabled(true); 315 // Add the new progress bar. 316 inner_pane.add(progress, BorderLayout.CENTER); 317 inner_pane.updateUI(); 318 } 319 319 // Otherwise if expected is not zero move the progress bar and 320 320 // update percent complete. 321 322 323 324 325 326 327 328 321 else if (expected != 0) { 322 progress.setValue((new Long(file_size)).intValue()); 323 int p_c = 324 (new Double( 325 progress.getPercentComplete() * 100)).intValue(); 326 progress.setString(p_c + "%"); 327 progress.setStringPainted(true); 328 } 329 329 // Finally, in the case we have no content length, we'll instead 330 330 // write the current number of bytes downloaded again. 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 331 else { 332 progress.setString( file_size + " bytes"); 333 progress.setStringPainted(true); 334 } 335 } 336 refresh(); 337 } 338 339 /** Retrieve a String from the dictionary using no arguments. 340 * @param key The String which acts as a key mapping for the 341 * ResourceBundle. 342 * @return A String which is the value for the given key. 343 */ 344 private String get(String key) { 345 return get(key, null); 346 } 347 348 /** Retrieve a String from the dictionary using the given arguments. 349 * @param key The String which acts as a key mapping for the 350 * ResourceBundle. 351 * @param args A String array of arguments to be filled out inside the 352 * dictionary value. 353 * @return A String which is the value for the given key. 354 */ 355 private String get(String key, String args[]) { 356 if(key.indexOf('.') == -1) { 357 return gatherer.dictionary.get("GProgressBar."+key, args); 358 } 359 return gatherer.dictionary.get(key, args); 360 } 361 362 /** The given parameter is taken as the number of bytes and is 363 * formatted into a strings such as: 364 * 45 bytes 365 * 1.21 Kbytes 366 * 2.12 Mbytes 367 * etc 368 * @param size The number to be formatted, in bytes, as a Long. 369 * @return A String which contains the size formatting into a 370 * nice little number - unit label. 371 */ 372 private String formatMetric(long size) { 373 if(size > 1024) { 374 return (size / 1024) + " Kbytes"; 375 } 376 return size + " bytes"; 377 } 378 379 /** Causes the two labels associated with this GProgressBar object to 380 * update, thus reflecting the progression of the download. This 381 * method is called by any of the other public setter methods in this 382 * class. 383 */ 384 private void refresh() { 385 // Refresh the contents of main label. 386 String args1[] = new String[1]; 387 args1[0] = initial_url.toString(); 388 388 389 390 391 392 389 //main_status.setText(get("Main_Status", args1)); 390 main_status.setText("Mirroring " + args1[0] + "."); 391 392 if(current_url != null) { 393 393 // Refresh the current label contents. 394 395 394 String args2[] = new String[1]; 395 args2[0] = current_url; 396 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 397 String cstext = "Downloading " + args2[0]; 398 current_status.setText(Utility.trim(cstext, 50)); 399 } 400 else if(current_action == Job.STOPPED 401 || current_action == Job.PAUSED) { 402 current_status.setText("Waiting for user action."); 403 } 404 else { 405 current_status.setText("Mirroring Complete."); 406 } 407 408 // Refresh the contents of results label 409 String args3[] = new String[4]; 410 args3[0] = file_count + ""; 411 args3[1] = total_count + ""; 412 args3[2] = warning_count + ""; 413 args3[3] = err_count + ""; 414 415 results_status.setText("Downloaded " + args3[0] + " of " + 416 args3[1] + " files (" + args3[2] + 417 " warnings, " + args3[3] + " errors)"); 418 419 this.updateUI(); 420 } 421 421 } 422 423 424 425 426 427 -
trunk/gli/src/org/greenstone/gatherer/gui/GPrompt.java
r4293 r4367 46 46 */ 47 47 public class GPrompt 48 49 48 extends JDialog 49 implements ActionListener { 50 50 51 51 private JButton close; 52 52 53 53 private JPanel content_pane; 54 54 55 56 57 55 // Static 56 static private Dimension SIZE = new Dimension(420, 140); 57 static private Dimension TEXT_SIZE = new Dimension(380, 60); 58 58 59 60 61 62 59 public GPrompt(Dialog owner, String title, String message, String left_image, String right_image) { 60 super(owner); 61 build_dialog(title, message, left_image, right_image); 62 } 63 63 64 65 66 67 64 public GPrompt(Frame owner, String title, String message, String left_image, String right_image) { 65 super(owner); 66 build_dialog(title, message, left_image, right_image); 67 } 68 68 69 70 69 public void actionPerformed(ActionEvent event) { 70 if(event.getSource() == close) { 71 71 // Check the show setting. 72 73 74 72 this.dispose(); 73 } 74 } 75 75 76 77 78 79 76 public void destroy() { 77 close = null; 78 content_pane = null; 79 } 80 80 81 82 83 81 public void display() { 82 this.show(); 83 } 84 84 85 86 87 88 89 90 91 92 93 94 85 /** This private method creates and lays out the components within this 86 * dialog box based on its arguments. 87 * @param message A String content to be displayed. 88 * @param left_name The name of the left image as a String. 89 * @param right_name The name of the right image as a String. 90 */ 91 private void build_dialog(String title, String message, String left_name, String right_name) { 92 this.setModal(true); 93 this.setSize(SIZE); 94 this.setTitle(title); 95 95 96 97 98 96 // Create components 97 content_pane = (JPanel) this.getContentPane(); 98 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false)); 99 99 100 101 102 103 104 105 100 JLabel image_left_label = null; 101 if(left_name != null) { 102 ImageIcon image_left = Utility.getImage(left_name); 103 image_left_label = new JLabel(image_left); 104 image_left_label.setOpaque(false); 105 } 106 106 107 108 107 JPanel text_pane = new JPanel(); 108 text_pane.setOpaque(false); 109 109 110 111 112 113 114 115 116 110 JTextArea text = new JTextArea(message); 111 text.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 112 text.setColumns(40); 113 text.setEditable(false); 114 text.setLineWrap(true); 115 text.setRows(3); 116 text.setWrapStyleWord(true); 117 117 118 119 120 121 122 123 118 JLabel image_right_label = null; 119 if(right_name != null) { 120 ImageIcon image_right = Utility.getImage(right_name); 121 image_right_label = new JLabel(image_right); 122 image_right_label.setOpaque(false); 123 } 124 124 125 126 127 125 close = new JButton(get("General.Close")); 126 close.addActionListener(this); 127 close.setBackground(Gatherer.config.getColor("coloring.button_background", false)); 128 128 129 130 131 132 129 // Layout components 130 text_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5)); 131 text_pane.setLayout(new BorderLayout()); 132 text_pane.add(text, BorderLayout.CENTER); 133 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 134 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 135 content_pane.setLayout(new BorderLayout()); 136 if(image_left_label != null) { 137 content_pane.add(image_left_label, BorderLayout.WEST); 138 } 139 content_pane.add(text_pane, BorderLayout.CENTER); 140 content_pane.add(close, BorderLayout.SOUTH); 141 if(image_right_label != null) { 142 content_pane.add(image_right_label, BorderLayout.EAST); 143 } 144 // Locate dialog on screen. 145 Dimension screen_size = Gatherer.config.screen_size; 146 this.setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 147 } 148 148 149 150 151 149 private String get(String key) { 150 return get(key, null); 151 } 152 152 153 154 155 156 157 158 153 private String get(String key, String args[]) { 154 if(key.indexOf(".") == -1) { 155 key = "GPrompt."+key; 156 } 157 return Gatherer.dictionary.get(key, args); 158 } 159 159 } -
trunk/gli/src/org/greenstone/gatherer/gui/GTextArea.java
r4293 r4367 46 46 47 47 public class GTextArea 48 48 extends JTextArea { 49 49 50 50 boolean tab_action = true; 51 51 52 53 52 static final public boolean INSERT_TAB_CHARACTER = true; 53 static final public boolean FOCUS_NEXT_COMPONENT = false; 54 54 55 56 57 58 59 60 61 55 /** Default constructor that simply calls superclass constructor. 56 * @param content A String specifying the initial content of this text 57 * component. 58 */ 59 public GTextArea(String content) { 60 super(content); 61 } 62 62 63 64 65 66 67 68 69 70 71 72 63 /** Constructor which also takes an argument specifying how this TextArea 64 * should respond to tab key presses. 65 * @param content A String specifying the initial content of this text 66 * component. 67 * @param tab_action A Boolean indicating the desired tab effect. 68 */ 69 public GTextArea(String content, boolean tab_action) { 70 super(content); 71 this.tab_action = tab_action; 72 } 73 73 74 75 76 77 78 79 80 81 82 83 84 74 /** Called to determine whether this TextArea is handling tab presses 75 * internally (INSERT_TAB_CHARACTER) or whether the focus manager should 76 * handle them (FOCUS_NEXT_COMPONENT). 77 * @return A Boolean indicating if the tab key presses are being managed 78 * internally, ie should tab traversal be disabled. 79 * @deprecated 80 */ 81 /** public boolean isManagingFocus() { 82 return tab_action; 83 } 84 */ 85 85 86 87 88 89 90 91 86 /** Sets how the TextArea should respond to tab key presses. 87 * @param tab_action A Boolean indicating the desired tab effect. 88 */ 89 public void setTabAction(boolean tab_action) { 90 this.tab_action = tab_action; 91 } 92 92 } 93 94 95 96 -
trunk/gli/src/org/greenstone/gatherer/gui/GUIManager.java
r4337 r4367 80 80 /** The GUIManager is in charge of creating the Gatherer window frame then filling it with the goodness of the view panes. GUIManager not only creates these panes, but allows some messaging between them. Furthermore GUIManager includes functionality from menu driven choices, simply as it was easier to put it here once and have it accessible from all pane children. */ 81 81 public class GUIManager 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 82 extends JFrame 83 implements ActionListener, ChangeListener { 84 /** The browsing pane behaves much like an internet browser, or at least will some day. */ 85 public BrowsingPane browser_pane = null; 86 /** The collection pane is more like a file manager where you drag files from one tree to another. */ 87 public CollectionPane collection_pane = null; 88 /** The create pane contains scripting options for importing and building collections into libraries. */ 89 public CreatePane create_pane = null; 90 91 public FileOpenActionListener foa_listener = new FileOpenActionListener(); 92 93 /** The configuration pane allows you to edit the design of the library in terms of the collection configuration file. */ 94 public GConfigPane config_pane = null; 95 /** A reference to the currently instantiated help window, if any. */ 96 public HelpFrame help = null; 97 /** The menu bar. */ 98 public MenuBar menu_bar = null; 99 /** The message pane is optional and contains the log of messages sent. */ 100 public MessagePane message_pane = null; 101 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 102 public MetaAuditFrame meta_audit; 103 /** The metaedit pane is used to assign, edit and remove metadata from files within the collection. */ 104 public MetaEditPane metaedit_pane = null; 105 /** The mirror pane contains controls for mirroring interent sites. */ 106 public MirrorPane mirror_pane = null; 107 /** The preview pane contains a preview of your build collection. */ 108 public PreviewPane preview_pane = null; 109 /** Are certain panes currently locked? */ 110 private boolean locked = false; 111 /** The size of the Gatherer window. */ 112 private Dimension size = null; 113 /** The filters used to dynamically filter the trees at user request. */ 114 private HashMap filters = new HashMap(); 115 /** The panel within the window that other components are placed on. */ 116 private JPanel content_pane = null; 117 /** The dummy export pane. */ 118 private JPanel export_pane = new JPanel(); 119 /** The last view pane selected. */ 120 private JPanel previous_pane; 121 /** The main tab pane containing the different views, available here to trap view change events. */ 122 private JTabbedPane tab_pane = null; 123 /** A reference to any existing search and replace module/dialog. */ 124 private SearchAndReplace sar = null; 125 /** A threaded tab changer to try and avoid NPE on exit. */ 126 private TabUpdater tab_updater = null; 127 /** The thread group this manager, and hence its child graphical rendering threads, belong to. In a vain attempts to make the Dictionary work across threads. 128 * @see org.greenstone.gatherer.Dictionary 129 */ 130 private ThreadGroup thread_group = null; 131 /** Ensures that expansion events between like collection trees are synchronized. */ 132 private TreeSynchronizer collection_tree_sync = null; 133 /** Ensures that expansion events between like workspace trees are synchronized. */ 134 private TreeSynchronizer workspace_tree_sync = null; 135 /**Constructor. Enable window events and arranges all other components. 136 136 * @param size The intial <strong>Dimension</strong> of the screen. 137 137 * @param graphic The default <strong>GraphicsConfiguration</strong> for this platform. 138 138 */ 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 139 public GUIManager(Dimension size) { 140 super(); 141 // Initialization 142 this.help = new HelpFrame(); 143 this.size = size; 144 this.collection_tree_sync = new TreeSynchronizer(); 145 this.workspace_tree_sync = new TreeSynchronizer(); 146 // Make the Tool tip hang around for a rediculous amount of time. 147 ToolTipManager.sharedInstance().setDismissDelay(10000); 148 // Get a reference to the main thread group. Create a new thread, which defaults into the same thread group, then get its thread group. Easy. 149 Thread bob = new Thread(); 150 thread_group = bob.getThreadGroup(); 151 // Set up some other UI stuff. (fonts handled in Gatherer.main()) 152 UIManager.put("FileChooser.lookInLabelText", Gatherer.dictionary.get("SaveCollectionBox.Look_In")); 153 UIManager.put("FileChooser.filesOfTypeLabelText", Gatherer.dictionary.get("SaveCollectionBox.Files_Of_Type")); 154 UIManager.put("FileChooser.fileNameLabelText", Gatherer.dictionary.get("SaveCollectionBox.File_Name")); 155 } 156 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured. In this case we are listening to actions from the menu-bar, and should react appropriately. 157 157 * @param event An <strong>ActionEvent</strong> containing information about the action that has occured. 158 158 */ 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 159 public void actionPerformed(ActionEvent event) { 160 boolean cont = true; 161 Object esrc = event.getSource(); 162 // ************* 163 // File Options. 164 // ************* 165 if(esrc == menu_bar.file_associations) { 166 Gatherer.assoc_man.edit(); 167 } 168 else if(esrc == menu_bar.file_close) { 169 if(!Gatherer.c_man.saved()) { 170 cont = showSaveCollectionBox(true, false); 171 } 172 if(cont) { 173 tab_pane.setSelectedComponent(collection_pane); 174 } 175 } 176 else if(esrc == menu_bar.file_delete) { 177 DeleteCollectionPrompt dcp = new DeleteCollectionPrompt(); 178 dcp.display(); 179 dcp.destroy(); 180 dcp = null; 181 System.gc(); 182 } 183 else if(esrc == menu_bar.file_exit) { 184 exit(); 185 } 186 186 else if(esrc == menu_bar.file_new) { 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 */ 359 360 361 362 363 364 365 187 if(!Gatherer.c_man.saved()) { 188 cont = showSaveCollectionBox(true, false); 189 } 190 if(cont) { 191 try { 192 while(Gatherer.c_man.ready()) { 193 wait(10); 194 } 195 } 196 catch(Exception error) { 197 } 198 showNewCollectionPrompt(); 199 } 200 } 201 else if(esrc == menu_bar.file_open) { 202 if(!Gatherer.c_man.saved()) { 203 cont = showSaveCollectionBox(true, false); 204 } 205 if(cont) { 206 try { 207 while(Gatherer.c_man.ready()) { 208 wait(10); 209 } 210 } 211 catch(Exception error) { 212 } 213 if(!showLoadCollectionBox()) { 214 collectionChanged(false); 215 } 216 } 217 } 218 else if(esrc == menu_bar.file_options) { 219 new Preferences(); 220 } 221 else if(esrc == menu_bar.file_save) { 222 Gatherer.c_man.saveCollection(false, false); 223 } 224 else if(esrc == menu_bar.file_save_as) { 225 String name = JOptionPane.showInputDialog(this, "Enter new collection filename."); 226 if(name != null) { 227 Gatherer.c_man.saveCollectionAs(name); 228 } 229 } 230 // ************* 231 // Edit Options. 232 // ************* 233 else if(esrc == menu_bar.edit_copy) { 234 try { 235 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 236 // Get the component with selected text as a JTextComponent 237 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();//getFocusOwner(); 238 text.copy(); 239 } 240 catch (Exception cce) { 241 // If the component is not a text component ignore the cut command 242 cce.printStackTrace(); 243 } 244 } 245 else if(esrc == menu_bar.edit_cut) { 246 try { 247 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 248 // Get the component with selected text as a JTextComponent 249 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner(); 250 // Cut the text to the clipboard 251 text.cut(); 252 } 253 catch (ClassCastException cce) { 254 // If the component is not a text component ignore the cut command 255 cce.printStackTrace(); 256 } 257 } 258 else if(esrc == menu_bar.edit_paste) { 259 try { 260 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 261 // Get the component with selected text as a JTextComponent 262 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner(); 263 // Cut the text to the clipboard 264 text.paste(); 265 } 266 catch (ClassCastException cce) { 267 // If the component is not a text component ignore the cut command 268 cce.printStackTrace(); 269 } 270 } 271 else if(esrc == menu_bar.edit_search) { 272 if(sar != null) { 273 sar.dispose(); 274 } 275 sar = new SearchAndReplace(false); 276 } 277 else if(esrc == menu_bar.edit_replace) { 278 if(sar != null) { 279 sar.dispose(); 280 } 281 sar = new SearchAndReplace(true); 282 } 283 // ************* 284 // Tools Options. 285 // ************* 286 else if(esrc == menu_bar.tools_size) { 287 FileNode records[] = metaedit_pane.getSelectedNode(); 288 if(records != null && records.length > 0) { 289 ArrayList metadatum = Gatherer.c_man.getCollection().gdm.getMetadata(records[0].getFile()); 290 if(metadatum.size() >= 4) { 291 Metadata metadata = (Metadata) metadatum.get(0); 292 ElementWrapper ew = metadata.getElement(); 293 294 int SIZE = 5000; 295 Object[] array = new Object[SIZE]; 296 Runtime.getRuntime().gc(); 297 long start = Runtime.getRuntime().freeMemory(); 298 for (int i = 0; i < SIZE; i++) { 299 array[i] = ew.copy(); 300 } 301 Runtime.getRuntime().gc(); 302 long end = Runtime.getRuntime().freeMemory(); 303 long difference = (( start - end ) / SIZE); 304 ///ystem.out.println(difference + " bytes used." ); 305 } 306 } 307 } 308 // ************* 309 // Help Options. 310 // ************* 311 else if(esrc == menu_bar.help_about) { 312 new AboutDialog(this); 313 } 314 else if(esrc == menu_bar.help_browse) { 315 help.setView("3.0"); 316 } 317 else if(esrc == menu_bar.help_build) { 318 help.setView("8.0"); 319 } 320 else if(esrc == menu_bar.help_collect) { 321 help.setView("5.0"); 322 } 323 else if(esrc == menu_bar.help_design) { 324 help.setView("7.0"); 325 } 326 else if(esrc == menu_bar.help_general) { 327 help.setView(""); 328 } 329 else if(esrc == menu_bar.help_metaedit) { 330 help.setView("6.0"); 331 } 332 else if(esrc == menu_bar.help_mirror) { 333 help.setView("4.0"); 334 } 335 else if(esrc == menu_bar.help_preview) { 336 help.setView("9.0"); 337 } 338 // ***************** 339 // Metadata Options. 340 // ***************** 341 else if(esrc == menu_bar.metadata_add) { 342 Gatherer.c_man.getCollection().msm.importMDS(); 343 } 344 else if(esrc == menu_bar.metadata_edit) { 345 showEditMetadataBox(); 346 } 347 else if(esrc == menu_bar.metadata_export) { 348 Gatherer.c_man.getCollection().msm.exportMDS(); 349 } 350 else if(esrc == menu_bar.metadata_view) { 351 showMetaAuditBox(); 352 } 353 else if(esrc == menu_bar.tools_log) { 354 showLogBox(); 355 } 356 } 357 /** Any actions that should happen after the display of the Gatherer window can be called here. Currently only updates the browser pane if it is active to work around bug in Mozilla renderer implementation. 358 */ 359 public void afterDisplay() { 360 if(Gatherer.config.get("workflow.mirror", true)) { 361 browser_pane.afterDisplay(); 362 } 363 metaedit_pane.afterDisplay(); 364 } 365 /** Once a collection has been made available to Gatherer, either by its creation or by it being reloaded, we need to inform all the visual components to update necessary data components (such as tree models), enable certain controls that depend on a collection being accessible, and refresh themselves. 366 366 * @param ready <i>true</i> if the collection is ready for editing, <i>false</i> otherwise. 367 367 */ 368 369 370 371 372 373 374 375 376 377 378 379 380 381 368 public void collectionChanged(final boolean ready) { 369 collection_tree_sync.clear(); // Clear any mappings in the tree synchronizers as being old news. 370 workspace_tree_sync.clear(); 371 if(Gatherer.config.get("workflow.mirror", true)) { 372 mirror_pane.collectionChanged(ready); 373 } 374 menu_bar.collectionChanged(ready); // Inform the menu bar that the collections changed. 375 collection_pane.collectionChanged(ready); // Used to update the collection workspace. 376 metaedit_pane.collectionChanged(ready); // Very important that metaedit pane shows current collection and is listening to latest msm. 377 config_pane.collectionChanged(ready); // Also important config pane is listening to latest msm. 378 create_pane.collectionChanged(ready); // Used to indicate a new BuildOptions model should be loaded. 379 // Force tree model updates. 380 Gatherer.c_man.refreshTrees(); 381 if(!locked) { 382 382 // Now enable tabs as necessary. Do this on event queue to prevent crazy NPEs 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 */ 404 405 406 407 408 409 410 411 412 413 414 415 416 383 if(tab_updater == null) { 384 tab_updater = new TabUpdater(tab_pane, ready); 385 } 386 else { 387 tab_updater.setReady(ready); 388 } 389 SwingUtilities.invokeLater(tab_updater); 390 } 391 // Finally display the collection name in the title bar. 392 if(ready) { 393 this.setTitle(Utility.PROGRAM_NAME + ":\"" + Gatherer.c_man.getCollection().getTitle() + "\""); 394 } 395 else { 396 this.setTitle(Utility.PROGRAM_NAME + ": " + get("Collection.No_Collection")); 397 } 398 // Now is a good time to force a garbage collect. 399 ///ystem.err.println("Calling garbage collection."); 400 System.gc(); 401 } 402 /** Enabled events on the window to be trapped, creates all the visual components, then builds the tab and other layouts. 403 */ 404 public void display() { 405 content_pane = (JPanel) this.getContentPane(); 406 // Enable window-type events to be fired. 407 enableEvents(AWTEvent.WINDOW_EVENT_MASK); 408 // Initialise and layout sub-components, plus other window dressing. 409 try { 410 this.setSize(size); 411 if(Gatherer.c_man.ready()) { 412 this.setTitle(Utility.PROGRAM_NAME + ":\"" + Gatherer.c_man.getCollection().getTitle() + "\""); 413 } 414 else { 415 this.setTitle(Utility.PROGRAM_NAME + ": " + get("Collection.No_Collection")); 416 } 417 417 // Pretty corner icon 418 418 this.setIconImage(Utility.getImage("gatherer_small.gif").getImage()); 419 419 // BorderLayout for the main screen. I'll try my best to avoid t 420 420 // hese in subcomponents as they're space greedy. 421 421 content_pane.setLayout(new BorderLayout()); 422 422 // Create the menu-bar and stick it up the top. 423 424 423 menu_bar = new MenuBar(new MenuListenerImpl()); 424 content_pane.add(menu_bar, BorderLayout.NORTH); 425 425 // Create the tabbed pane and plop it in the center where it will 426 426 // expand to consume all available space like any good gas would. 427 428 429 427 tab_pane = new JTabbedPane(); 428 tab_pane.addChangeListener(this); 429 tab_pane.setFont(Gatherer.config.getFont("general.font", false)); 430 430 431 431 // May have to play with the order in which tabs are added. 432 433 434 435 436 432 if(Gatherer.config.get("workflow.browse", true)) { 433 browser_pane = new BrowsingPane(); 434 tab_pane.addTab(get("Browser"), Utility.getImage("browsing.gif"), browser_pane); 435 tab_pane.setEnabledAt(tab_pane.indexOfComponent(browser_pane), Gatherer.config.get("workflow.browse", false)); 436 } 437 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 438 if(Gatherer.config.get("workflow.mirror", true)) { 439 mirror_pane = new MirrorPane(workspace_tree_sync); 440 mirror_pane.display(); 441 tab_pane.addTab(get("Mirroring"), Utility.getImage("mirroring.gif"), mirror_pane); 442 tab_pane.setEnabledAt(tab_pane.indexOfComponent(mirror_pane), Gatherer.config.get("workflow.mirror", false)); 443 } 444 445 if(Gatherer.config.get("workflow.gather", true)) { 446 collection_pane = new CollectionPane(workspace_tree_sync, collection_tree_sync); 447 collection_pane.display(); 448 tab_pane.addTab(get("Collection"), Utility.getImage("collection.gif"), collection_pane); 449 tab_pane.setEnabledAt(tab_pane.indexOfComponent(collection_pane), Gatherer.config.get("workflow.gather", false)); 450 } 451 452 if(Gatherer.config.get("workflow.enrich", true)) { 453 metaedit_pane = new MetaEditPane(collection_tree_sync); 454 metaedit_pane.display(); 455 tab_pane.addTab(get("MetaEdit"), Utility.getImage("metaedit.gif"), metaedit_pane); 456 tab_pane.setEnabledAt(tab_pane.indexOfComponent(metaedit_pane), false); 457 } 458 458 459 460 461 462 463 464 459 if(Gatherer.config.get("workflow.design", true)) { 460 config_pane = new GConfigPane(); 461 config_pane.display(); 462 tab_pane.addTab(get("Build"), Utility.getImage("build.gif"), config_pane); 463 tab_pane.setEnabledAt(tab_pane.indexOfComponent(config_pane), false); 464 } 465 465 466 467 468 469 466 if(Gatherer.config.get("workflow.export", true)) { 467 tab_pane.addTab(get("Export"), Utility.getImage("export.gif"), export_pane); 468 tab_pane.setEnabledAt(tab_pane.indexOfComponent(export_pane), false); 469 } 470 470 471 472 473 474 475 476 471 if(Gatherer.config.get("workflow.create", true)) { 472 create_pane = new CreatePane(); 473 create_pane.display(); 474 tab_pane.addTab(get("Create"), Utility.getImage("build session.gif"), create_pane); 475 tab_pane.setEnabledAt(tab_pane.indexOfComponent(create_pane), false); 476 } 477 477 478 479 480 481 482 483 478 if(Gatherer.config.get("workflow.preview", true)) { 479 preview_pane = new PreviewPane(); 480 preview_pane.display(); 481 tab_pane.addTab(get("Preview"), Utility.getImage("final.gif"), preview_pane); 482 tab_pane.setEnabledAt(tab_pane.indexOfComponent(preview_pane), false); 483 } 484 484 485 485 // Find the first tab that is enabled and select that. 486 487 488 489 490 491 492 493 494 486 boolean found = false; 487 for(int i = 0; !found && i < tab_pane.getTabCount(); i++) { 488 if(tab_pane.isEnabledAt(i)) { 489 tab_pane.setSelectedIndex(i); 490 found = true; 491 } 492 } 493 494 content_pane.add(tab_pane, BorderLayout.CENTER); 495 495 // Drive a sessionReady event to update all controls to reflect current collection status. 496 497 498 499 496 collectionChanged(Gatherer.c_man.ready()); 497 } 498 catch (Exception e) { 499 Gatherer.printStackTrace(e); 500 500 // The GUI failing to build is a app killer 501 502 503 504 505 506 */ 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 */ 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 501 e.printStackTrace(); 502 System.exit(1); 503 } 504 } 505 /** When called this method ensures that all the things needing saving are saved before Gatherer.exit() is called. This includes a save collection prompt if necessary. 506 */ 507 public void exit() { 508 boolean cont = true; 509 if(Gatherer.c_man.ready() && !Gatherer.c_man.saved()) { 510 cont = showSaveCollectionBox(false, true); 511 } 512 else { 513 help.destroy(); 514 help = null; 515 Gatherer.self.exit(); 516 } 517 } 518 /** Retrieve the filter, or if one already exists, spawn a linked copy. */ 519 public Filter getFilter(DragTree tree) { 520 Filter filter = (Filter) filters.get(tree.getModel()); 521 if(filter == null) { 522 filter = new Filter(tree, null); 523 filters.put(tree.getModel(), filter); 524 return filter; 525 } 526 return filter.spawn(tree); 527 } 528 529 public Component getSelectedView() { 530 return tab_pane.getSelectedComponent(); 531 } 532 /** This method is called when the collection is being built, and is used to disable all controls in all pane which could change the state of the collection. 533 */ 534 public void lockCollection(boolean import_stage, boolean lock) { 535 locked = lock; 536 if(import_stage) { 537 int collection_pos = tab_pane.indexOfComponent(collection_pane); 538 int metaedit_pos = tab_pane.indexOfComponent(metaedit_pane); 539 int config_pos = tab_pane.indexOfComponent(config_pane); 540 tab_pane.setEnabledAt(collection_pos, !lock); 541 tab_pane.setEnabledAt(metaedit_pos, !lock); 542 tab_pane.setEnabledAt(config_pos, !lock); 543 } 544 else { 545 int config_pos = tab_pane.indexOfComponent(config_pane); 546 tab_pane.setEnabledAt(config_pos, !lock); 547 } 548 } 549 550 public void refreshTrees() { 551 collection_pane.refreshTrees(); 552 //metaedit_pane.refreshTrees(); 553 } 554 555 /** Allows the system to programatically set the selected tab. 556 556 * @param component The view you wish to make visable in the tab pane as a <strong>Component</strong>. 557 557 */ 558 559 560 561 562 563 564 565 566 567 568 558 public void setSelectedView(Component component) { 559 tab_pane.setSelectedComponent(component); 560 } 561 562 /** Specifies whether a certain tab is enabled or not. */ 563 public void setTabEnabled(String rawname, boolean state) { 564 // Retrieve the dictionary based name. 565 String name = get(rawname); 566 int index = tab_pane.indexOfTab(name); 567 // Of course we may not have this tab available. 568 if(index != -1) { 569 569 // Some tabs are also dependant on if a collection is ready 570 571 572 573 574 575 576 577 578 579 570 Component component = tab_pane.getComponentAt(index); 571 if(component == preview_pane) { 572 tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready() && Gatherer.c_man.built()); 573 } 574 else if(component == metaedit_pane || component == config_pane || component == export_pane || component == create_pane) { 575 tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready()); 576 } 577 else { 578 tab_pane.setEnabledAt(index, state); 579 } 580 580 // If this was the currently selected tab and it is now disabled, change the view to the first enabled tab. 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 */ 599 600 601 602 603 604 605 */ 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 */ 626 627 628 629 630 */ 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 */ 650 651 652 653 654 655 656 657 658 659 581 if(tab_pane.getSelectedIndex() == index && !state) { 582 boolean found = false; 583 for(int i = 0; !found && i < tab_pane.getTabCount(); i++) { 584 if(tab_pane.isEnabledAt(i)) { 585 tab_pane.setSelectedIndex(i); 586 found = true; 587 } 588 } 589 // If there are no tabs enabled, which should be impossible, then select the first tab 590 if(!found) { 591 tab_pane.setSelectedIndex(0); 592 } 593 } 594 } 595 } 596 597 /** When the edit metadata option is choosen from the menu, this method is called to ensure we only edit the metadata if there is metadata loaded. 598 */ 599 public void showEditMetadataBox() { 600 if(Gatherer.c_man.getCollection() != null) { 601 Gatherer.c_man.getCollection().msm.editMDS(); 602 } 603 } 604 /** When the load collection option is choosen this method is called to produce the modal file load prompt. 605 */ 606 public boolean showLoadCollectionBox() { 607 boolean result = false; 608 //LoadCollectionBox load_collection_box = new LoadCollectionBox(); 609 File file; 610 if(Gatherer.config.gsdl_path != null) { 611 file = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)); 612 } 613 else { 614 file = new File(Utility.BASE_DIR); 615 } 616 OpenCollectionDialog chooser = new OpenCollectionDialog(file); 617 String filename = chooser.getFileName(); 618 // User can cancel action. 619 if(filename != null) { 620 result = Gatherer.c_man.loadCollection(filename); 621 } 622 return result; 623 } 624 /** When called this method causes the Log class in Gatherer to display a nice dialog box which contains the log. 625 */ 626 public void showLogBox() { 627 Gatherer.log.display(); 628 } 629 /** When called this method causes the MetaAuditBox class in CollectionManager to display a nice dialog box which contains all the metadata assigned in the collection. 630 */ 631 public void showMetaAuditBox() { 632 if(meta_audit == null) { 633 FileNode records[] = metaedit_pane.getSelectedNode(); 634 if(records == null) { 635 records = collection_pane.getSelected(); 636 } 637 if(records != null) { 638 wait(true); 639 meta_audit = new MetaAuditFrame(collection_tree_sync, records); 640 } 641 } 642 if(meta_audit != null) { 643 wait(true); 644 meta_audit.display(); 645 } 646 wait(false); 647 } 648 /** This method is used to open the new collection box on the screen. 649 */ 650 public void showNewCollectionPrompt() { 651 NewCollectionMetadataPrompt ncm_prompt = null; 652 // Create the collection details prompt from new collection prompt 653 NewCollectionDetailsPrompt ncd_prompt = new NewCollectionDetailsPrompt(); 654 // If no previous collection was indicated as a model design, then show the metadata selection prompt from new collection prompt 655 if(!ncd_prompt.isCancelled() && (ncd_prompt.getBase() == null)) { 656 ncm_prompt = new NewCollectionMetadataPrompt(); 657 } 658 // Create the new collection (if not cancelled) in a new thread. 659 if(!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) { 660 660 // Create new collection. 661 662 661 CreationTask task = new CreationTask(ncd_prompt, ncm_prompt); 662 SwingUtilities.invokeLater(task); 663 663 // Close prompt. 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 */ 696 697 698 699 664 } 665 // Done 666 ncd_prompt = null; 667 ncm_prompt = null; 668 } 669 private class CreationTask 670 implements Runnable { 671 private NewCollectionDetailsPrompt ncd_prompt = null; 672 private NewCollectionMetadataPrompt ncm_prompt = null; 673 public CreationTask(NewCollectionDetailsPrompt ncd_prompt, NewCollectionMetadataPrompt ncm_prompt) { 674 this.ncd_prompt = ncd_prompt; 675 this.ncm_prompt = ncm_prompt; 676 } 677 678 public void run() { 679 if(ncm_prompt == null) { 680 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), ncd_prompt.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), ncd_prompt.getBase(), null); 681 } 682 else { 683 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), ncd_prompt.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), null, ncm_prompt.getSets()); 684 } 685 ncd_prompt.dispose(); 686 ncd_prompt = null; 687 if(ncm_prompt != null) { 688 ncm_prompt.dispose(); 689 ncm_prompt = null; 690 } 691 } 692 } 693 694 /** This method is used to open the options box on the screen. 695 */ 696 public void showOptionsBox() { 697 new OptionsBox(); 698 } 699 /** This method is used to open the save collection box/prompt on the screen. 700 700 * @return A <i>boolean</i> which is <i>true</i> if the collection was saved successfully, <i>false</i> otherwise. 701 701 */ 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 702 public boolean showSaveCollectionBox(boolean close_after, boolean exit_after) { 703 //SaveCollectionBox save_collection_box = new SaveCollectionBox(); 704 //Rectangle bounds = save_collection_box.getBounds(); 705 //int result = save_collection_box.getUserOption(Gatherer.c_man.getCollection().getName()); 706 //switch(result) { 707 //case SaveCollectionBox.SAVE_YES: 708 Gatherer.c_man.saveCollection(close_after, exit_after); 709 //content_pane.paintImmediately(bounds); 710 return true; 711 //case SaveCollectionBox.SAVE_NO: 712 // Close collection. 713 // if(close_after) { 714 // tab_pane.setSelectedComponent(collection_pane); 715 // Gatherer.c_man.closeCollection(); 716 // } 717 // if(exit_after) { 718 // Gatherer.self.exit(); 719 // } 720 // return true; 721 //default: 722 // return false; 723 //} 724 } 725 /** Any implementation of ChangeListener must include this method so we can be informed when the state of one of the registered objects changes. In this case we are listening to view changes within the tabbed pane. 726 726 * @param event A ChangeEvent containing information about the event that fired this call. 727 727 */ 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 728 public void stateChanged(ChangeEvent event) { 729 if(previous_pane != null) { 730 if(previous_pane == create_pane) { 731 create_pane.loseFocus(); 732 } 733 } 734 menu_bar.tabSelected(tab_pane.getSelectedIndex()); 735 if(tab_pane.getSelectedIndex() == tab_pane.indexOfComponent(collection_pane)) { 736 menu_bar.metadata_view.setEnabled(true); 737 } 738 else if(tab_pane.getSelectedIndex() == tab_pane.indexOfComponent(metaedit_pane)) { 739 metaedit_pane.gainFocus(); 740 menu_bar.metadata_view.setEnabled(true); 741 } 742 else if(tab_pane.getSelectedIndex() == tab_pane.indexOfComponent(config_pane)) { 743 config_pane.gainFocus(); 744 menu_bar.metadata_view.setEnabled(false); 745 } 746 else if(tab_pane.getSelectedIndex() == tab_pane.indexOfComponent(create_pane)) { 747 create_pane.gainFocus(); 748 menu_bar.metadata_view.setEnabled(false); 749 } 750 else if(tab_pane.getSelectedIndex() == tab_pane.indexOfComponent(preview_pane)) { 751 config_pane.saveConfiguration(); 752 preview_pane.gainFocus(); 753 menu_bar.metadata_view.setEnabled(false); 754 } 755 else { 756 menu_bar.metadata_view.setEnabled(false); 757 } 758 previous_pane = (JPanel) tab_pane.getSelectedComponent(); 759 } 760 761 public void wait(boolean waiting) { 762 Component glass_pane = getGlassPane(); 763 if(waiting) { 764 764 // Show wait cursor. 765 766 767 768 765 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 766 glass_pane.setVisible(true); 767 } 768 else { 769 769 // Hide wait cursor. 770 771 772 773 774 775 776 777 778 779 780 781 782 770 glass_pane.setVisible(false); 771 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 772 } 773 glass_pane = null; 774 } 775 776 public void workflowUpdate(String raw, boolean state) { 777 WorkflowUpdater task = new WorkflowUpdater(raw, state); 778 SwingUtilities.invokeLater(task); 779 task = null; 780 } 781 782 /** Retrieves a phrase from the Dictionary based on the key. 783 783 * @param key A <strong>String</strong> uniquely identifying a phrase from the Dictionary. 784 784 * @return The desired phrase as a <strong>String</strong>. 785 785 * @see org.greenstone.gatherer.Dictionary 786 786 */ 787 788 789 790 787 private String get(String key) { 788 return get(key, null); 789 } 790 /** Retrieves a phrase from the Dictionary based on the key and including the arguments. 791 791 * @param key A <strong>String</strong> uniquely identifying a phrase from the Dictionary. 792 792 * @param args A <strong>String[]</strong> of arguments available to be inserted into the phrase. … … 794 794 * @see org.greenstone.gatherer.Dictionary 795 795 */ 796 797 798 799 800 801 802 796 private String get(String key, String args[]) { 797 if(key.indexOf('.') == -1) { 798 key = "GUI." + key; 799 } 800 return Gatherer.dictionary.get(key, args); 801 } 802 /** Called to determine if we should wait for a thread to finish before continuing. We wait for threads if they are named: GSHELL_BUILD, GSHELL_IMPORT, or GSHELL_NEW. 803 803 * @return <i>true</i> if we should wait for a thread, <i>false</i> if it is safe to continue. 804 804 */ 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 805 private boolean waitForThread() { 806 Thread active[] = new Thread[thread_group.activeCount()]; 807 int size = thread_group.enumerate(active); 808 for(int i = 0; i < size; i++) { 809 if(active[i].getName().equals(GShell.GSHELL_BUILD) || 810 active[i].getName().equals(GShell.GSHELL_IMPORT) || 811 active[i].getName().equals(GShell.GSHELL_NEW)) { 812 return true; 813 } 814 } 815 return false; 816 } 817 818 819 /**Overridden from JFrame so we can exit safely when window is closed (or destroyed). 820 820 * @param event A <strong>WindowEvent</strong> containing information about the event that fred this call. 821 821 */ 822 protected void processWindowEvent(WindowEvent event) { 823 if(event.getID() == WindowEvent.WINDOW_CLOSING) { 824 exit(); 825 } 826 } 827 /** Listens to actions upon the menu bar, and if it detects a click over the help menu brings the help window to the front if it has become hidden. 828 */ 829 private class MenuListenerImpl 830 implements MenuListener { 831 /** Called whenever a popup menu is hidden, but we don't care. 822 protected void processWindowEvent(WindowEvent event) { 823 if(event.getID() == WindowEvent.WINDOW_CLOSING) { 824 exit(); 825 } 826 } 827 /** Listens to actions upon the menu bar, and if it detects a click over the help menu brings the help window to the front if it has become hidden. 828 */ 829 private class MenuListenerImpl 830 implements MenuListener { 831 /** Called whenever a popup menu is hidden, but we don't care. 832 * @param e Some <strong>MenuEvent</strong> that we could care less about. 833 */ 834 public void menuCanceled(MenuEvent e) { 835 } 836 /** Called whenever a menu header (ie button) becomes unselected, but we don't care. 832 837 * @param e Some <strong>MenuEvent</strong> that we could care less about. 833 838 */ 834 public void menuCanceled(MenuEvent e) { 835 } 836 /** Called whenever a menu header (ie button) becomes unselected, but we don't care. 837 * @param e Some <strong>MenuEvent</strong> that we could care less about. 838 */ 839 public void menuDeselected(MenuEvent e) { 840 } 841 /** This method, when a menu is first opened, is the only one we respond to by bringing the help window to the front if possible, but only if there is a help window and the help menu is the one opening. 839 public void menuDeselected(MenuEvent e) { 840 } 841 /** This method, when a menu is first opened, is the only one we respond to by bringing the help window to the front if possible, but only if there is a help window and the help menu is the one opening. 842 842 * @param e The <strong>MenuEvent</strong> whose source is checked. 843 843 */ 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 844 public void menuSelected(MenuEvent e) { 845 if(e.getSource() == menu_bar.help) { 846 if(menu_bar.help.isSelected()) { 847 menu_bar.help.doClick(10); 848 } 849 } 850 } 851 } 852 private class TabUpdater 853 implements Runnable { 854 private boolean ready = false; 855 private int browse_pos = -1; 856 private int mirror_pos = -1; 857 private int config_pos = -1; 858 private int create_pos = -1; 859 private int export_pos = -1; 860 private int metaedit_pos = -1; 861 private int preview_pos = -1; 862 private JTabbedPane tab_pane = null; 863 public TabUpdater(JTabbedPane tab_pane, boolean ready) { 864 this.ready = ready; 865 this.tab_pane = tab_pane; 866 browse_pos = tab_pane.indexOfComponent(browser_pane); 867 mirror_pos = tab_pane.indexOfComponent(mirror_pane); 868 metaedit_pos = tab_pane.indexOfComponent(metaedit_pane); 869 config_pos = tab_pane.indexOfComponent(config_pane); 870 export_pos = tab_pane.indexOfComponent(export_pane); 871 create_pos = tab_pane.indexOfComponent(create_pane); 872 preview_pos = tab_pane.indexOfComponent(preview_pane); 873 } 874 public void run() { 875 if(browse_pos != -1) { 876 if(ready) { 877 tab_pane.setEnabledAt(browse_pos, Gatherer.config.get("workflow.browse", false)); 878 } 879 else { 880 tab_pane.setEnabledAt(browse_pos, Gatherer.config.get("workflow.browse", true)); 881 } 882 } 883 if(mirror_pos != -1) { 884 if(ready) { 885 tab_pane.setEnabledAt(mirror_pos, Gatherer.config.get("workflow.mirror", false)); 886 } 887 else { 888 tab_pane.setEnabledAt(mirror_pos, Gatherer.config.get("workflow.mirror", true)); 889 } 890 } 891 if(metaedit_pos != -1) { 892 tab_pane.setEnabledAt(metaedit_pos, ready && Gatherer.config.get("workflow.enrich", false)); 893 } 894 if(config_pos != -1) { 895 tab_pane.setEnabledAt(config_pos, ready && Gatherer.config.get("workflow.design", false)); 896 } 897 if(export_pos != -1) { 898 tab_pane.setEnabledAt(export_pos, ready && Gatherer.config.get("workflow.export", false)); 899 } 900 if(create_pos != -1) { 901 tab_pane.setEnabledAt(create_pos, ready && Gatherer.config.get("workflow.create", false)); 902 } 903 if(preview_pos != -1) { 904 tab_pane.setEnabledAt(preview_pos, Gatherer.c_man != null && Gatherer.c_man.built() && Gatherer.config.get("workflow.preview", false)); 905 } 906 } 907 public void setReady(boolean ready) { 908 this.ready = ready; 909 } 910 } 911 912 private class WorkflowUpdater 913 implements Runnable { 914 private boolean state; 915 private String raw; 916 public WorkflowUpdater(String raw, boolean state) { 917 this.raw = raw; 918 this.state = state; 919 } 920 public void run() { 921 setTabEnabled(raw, state); 922 } 923 } 924 924 } 925 926 -
trunk/gli/src/org/greenstone/gatherer/gui/LockFileDialog.java
r4308 r4367 13 13 14 14 public class LockFileDialog 15 15 extends JDialog { 16 16 17 18 19 20 21 17 private int choice; 18 private Document document; 19 private JButton cancel_button; 20 private JButton ok_button; 21 private LockFileDialog self; 22 22 23 24 23 static final public int NO_OPTION = 0; 24 static final public int YES_OPTION = 1; 25 25 26 27 28 26 static final private Dimension LABEL_SIZE = new Dimension(100, 25); 27 static final private Dimension SIZE = new Dimension(500, 225); 28 static final private int ICON_SIZE = 30; 29 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 30 public LockFileDialog(JFrame parent, String name, File lock_file) { 31 super(parent, get("Title"), true); 32 setSize(SIZE); 33 this.self = this; 34 // Parse the lock file, but do so quietly so that if the XML is poorly formed it doesn't show exception. 35 document = Utility.parse(lock_file, false); 36 // Creation 37 JPanel content_pane = (JPanel) getContentPane(); 38 JPanel upper_pane = new JPanel(); 39 ImageIcon icon = Utility.getImage("lcolicn.gif"); 40 ImageIcon scaled_icon = new ImageIcon(icon.getImage().getScaledInstance(ICON_SIZE, ICON_SIZE, Image.SCALE_DEFAULT)); 41 JLabel icon_label = new JLabel(scaled_icon); 42 JPanel title_pane = new JPanel(); 43 JLabel title_one_label = new JLabel(get("General.Warning")); 44 JLabel title_two_label = new JLabel(get("Lockfile_Message_One")); 45 JPanel central_pane = new JPanel(); 46 JPanel name_pane = new JPanel(); 47 JLabel name_label = new JLabel(get("Name")); 48 name_label.setPreferredSize(LABEL_SIZE); 49 TextFieldLabel name_field = new TextFieldLabel(name); 50 JPanel person_pane = new JPanel(); 51 JLabel person_label = new JLabel(get("User")); 52 person_label.setPreferredSize(LABEL_SIZE); 53 TextFieldLabel person_field = new TextFieldLabel(getValue("User")); 54 JPanel machine_pane = new JPanel(); 55 JLabel machine_label = new JLabel(get("Machine")); 56 machine_label.setPreferredSize(LABEL_SIZE); 57 TextFieldLabel machine_field = new TextFieldLabel(getValue("Machine")); 58 JPanel created_pane = new JPanel(); 59 JLabel created_label = new JLabel(get("Date")); 60 created_label.setPreferredSize(LABEL_SIZE); 61 TextFieldLabel created_field = new TextFieldLabel(getValue("Date")); 62 JLabel central_label = new JLabel(get("Lockfile_Message_Two")); 63 JPanel button_pane = new JPanel(); 64 ok_button = new JButton(get("General.OK")); 65 cancel_button = new JButton(get("General.Cancel")); 66 // Connection 67 ok_button.addActionListener(new MyActionListener()); 68 cancel_button.addActionListener(new MyActionListener()); 69 // Layout 70 icon_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,10)); 71 71 72 73 74 72 title_pane.setLayout(new GridLayout(2,1,0,5)); 73 title_pane.add(title_one_label); 74 title_pane.add(title_two_label); 75 75 76 77 78 76 upper_pane.setLayout(new BorderLayout()); 77 upper_pane.add(icon_label, BorderLayout.WEST); 78 upper_pane.add(title_pane, BorderLayout.CENTER); 79 79 80 81 82 80 name_pane.setLayout(new BorderLayout()); 81 name_pane.add(name_label, BorderLayout.WEST); 82 name_pane.add(name_field, BorderLayout.CENTER); 83 83 84 85 86 84 person_pane.setLayout(new BorderLayout()); 85 person_pane.add(person_label, BorderLayout.WEST); 86 person_pane.add(person_field, BorderLayout.CENTER); 87 87 88 89 90 88 machine_pane.setLayout(new BorderLayout()); 89 machine_pane.add(machine_label, BorderLayout.WEST); 90 machine_pane.add(machine_field, BorderLayout.CENTER); 91 91 92 93 94 92 created_pane.setLayout(new BorderLayout()); 93 created_pane.add(created_label, BorderLayout.WEST); 94 created_pane.add(created_field, BorderLayout.CENTER); 95 95 96 97 98 99 100 101 96 central_pane.setLayout(new GridLayout(5,1,0,5)); 97 central_pane.add(name_pane); 98 central_pane.add(person_pane); 99 central_pane.add(machine_pane); 100 central_pane.add(created_pane); 101 central_pane.add(central_label); 102 102 103 104 105 103 button_pane.setLayout(new GridLayout(1,2,5,0)); 104 button_pane.add(ok_button); 105 button_pane.add(cancel_button); 106 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 107 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 108 content_pane.setLayout(new BorderLayout()); 109 content_pane.add(upper_pane, BorderLayout.NORTH); 110 content_pane.add(central_pane, BorderLayout.CENTER); 111 content_pane.add(button_pane, BorderLayout.SOUTH); 112 // Display 113 if(parent != null) { 114 Rectangle frame_bounds = parent.getBounds(); 115 setLocation(frame_bounds.x + (frame_bounds.width - SIZE.width) / 2, frame_bounds.y + (frame_bounds.height - SIZE.height) / 2); 116 } 117 else { 118 Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize(); 119 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 120 } 121 } 122 122 123 124 125 126 123 public int getChoice() { 124 show(); 125 return choice; 126 } 127 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 128 private String getValue(String name) { 129 String value = ""; 130 if(document != null) { 131 try { 132 Element value_element = (Element) MSMUtils.getNodeFromNamed(document.getDocumentElement(), name); 133 value = MSMUtils.getValue(value_element); 134 } 135 catch (Exception error) { 136 } 137 } 138 else { 139 value = get("Error"); 140 } 141 return value; 142 } 143 143 144 145 146 147 148 149 150 151 152 153 154 155 156 144 private class MyActionListener 145 implements ActionListener { 146 public void actionPerformed(ActionEvent event) { 147 if(event.getSource() == ok_button) { 148 choice = YES_OPTION; 149 } 150 else { 151 choice = NO_OPTION; 152 } 153 self.hide(); 154 self.dispose(); 155 } 156 } 157 157 158 159 160 161 162 163 164 165 158 static public void main(String[] args) { 159 JFrame frame = new JFrame(); 160 frame.setSize(640,480); 161 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 162 frame.show(); 163 LockFileDialog dialog = new LockFileDialog(frame, "Test", new File(args[0])); 164 int choice = dialog.getChoice(); 165 } 166 166 167 168 169 170 171 172 167 static private String get(String key) { 168 if(key.indexOf(".") == -1) { 169 key = "LockFileDialog." + key; 170 } 171 return Gatherer.dictionary.get(key); 172 } 173 173 } -
trunk/gli/src/org/greenstone/gatherer/gui/LongProgressBar.java
r4293 r4367 34 34 */ 35 35 final public class LongProgressBar 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 36 extends JProgressBar { 37 private BigInteger cur_value = null; 38 private BigInteger max_value = null; 39 private BigInteger min_value = null; 40 /** The previous percentage value. */ 41 private int previous = -1; 42 private SafeSetIndeterminate safe_set_indeterminate = null; 43 private SafeSetString safe_set_string = null; 44 private SafeSetValue safe_set_value = null; 45 public LongProgressBar() { 46 super(0, 100); 47 cur_value = BigInteger.ZERO; 48 min_value = BigInteger.ZERO; 49 max_value = BigInteger.ZERO; 50 } 51 52 public void addMaximum(int size) { 53 ///ystem.err.println("Add maximum " + size); 54 if(size > 0) { 55 max_value = max_value.add(new BigInteger((new Integer(size)).toString())); 56 update(); 57 } 58 } 59 60 public void addMaximum(long size) { 61 ///ystem.err.println("Add maximum " + size); 62 if(size > 0) { 63 max_value = max_value.add(new BigInteger((new Long(size)).toString())); 64 update(); 65 } 66 } 67 68 public void addValue(int size) { 69 ///ystem.err.println("Add value " + size); 70 if(size > 0) { 71 cur_value = cur_value.add(new BigInteger((new Integer(size)).toString())); 72 update(); 73 } 74 } 75 76 public void addValue(long size) { 77 ///ystem.err.println("Add value " + size); 78 if(size > 0) { 79 cur_value = cur_value.add(new BigInteger((new Long(size)).toString())); 80 update(); 81 } 82 } 83 84 public void refreshString() { 85 safeSetString(previous + "%"); 86 } 87 88 public void reset() { 89 cur_value = BigInteger.ZERO; 90 max_value = BigInteger.ZERO; 91 previous = -1; 92 update(); 93 } 94 95 public void setIndeterminate(boolean state) { 96 if(safe_set_indeterminate == null) { 97 safe_set_indeterminate = new SafeSetIndeterminate(state); 98 } 99 else { 100 safe_set_indeterminate.setState(state); 101 } 102 SwingUtilities.invokeLater(safe_set_indeterminate); 103 } 104 105 public void setMaximum(int size) { 106 ///ystem.err.println("Add maximum " + size); 107 if(size > 0) { 108 max_value = new BigInteger((new Integer(size)).toString()); 109 update(); 110 } 111 } 112 113 public void setMaximum(long size) { 114 ///ystem.err.println("Add maximum " + size); 115 if(size > 0) { 116 max_value = new BigInteger((new Long(size)).toString()); 117 update(); 118 } 119 } 120 121 public void setString(String label) { 122 safeSetString(label); 123 } 124 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 125 public void setValue(int size) { 126 ///ystem.err.println("Set value " + size); 127 cur_value = new BigInteger((new Integer(size)).toString()); 128 update(); 129 } 130 131 public void setValue(long size) { 132 ///ystem.err.println("Set value " + size); 133 cur_value = new BigInteger((new Long(size)).toString()); 134 update(); 135 } 136 137 /** This method is an unsafe way to set the progress bar to be indeterminate, -unless- it is called from the Event Queue. */ 138 public void unsafeSetIndeterminate(boolean state) { 139 super.setIndeterminate(state); 140 } 141 142 public void unsafeSetString(String label) { 143 super.setString(label); 144 } 145 146 public void unsafeSetValue(int value) { 147 ///ystem.err.println("Set value: " + value); 148 super.setValue(value); 149 } 150 151 private void update() { 152 int percentage = -1; 153 if(cur_value.equals(BigInteger.ZERO) || max_value.equals(BigInteger.ZERO)) { 154 percentage = 0; 155 } 156 else { 157 BigInteger tmp_value = cur_value.multiply(new BigInteger("100")); 158 BigInteger per_value = tmp_value.divide(max_value); 159 percentage = per_value.intValue(); 160 if(percentage > 100) { 161 percentage = 100; 162 } 163 } 164 if(percentage != previous) { 165 165 ///ystem.err.println("Progress bar status: value = " + getValue()); 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 166 previous = percentage; 167 safeSetValue(percentage); 168 safeSetString(percentage + "%"); 169 } 170 } 171 /** Change the string displayed on the progress bar. 172 * @param label The name progress bar label as a <strong>String</strong>. 173 * Original code: Tad Frysinger (TeamB) 174 */ 175 private void safeSetString(String label) { 176 if(safe_set_string == null) { 177 safe_set_string = new SafeSetString(label); 178 } 179 else { 180 safe_set_string.setLabel(label); 181 } 182 SwingUtilities.invokeLater(safe_set_string); 183 } 184 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 185 /** Increase the value of the progress bar. 186 * @param ammount The ammount to increase as an <i>int</i>. 187 * Original code: Tad Frysinger (TeamB) 188 */ 189 private void safeSetValue(final int ammount) { 190 // Update progress bar, 191 if(safe_set_value == null) { 192 safe_set_value = new SafeSetValue(ammount); 193 } 194 else { 195 safe_set_value.setValue(ammount); 196 } 197 SwingUtilities.invokeLater(safe_set_value); 198 } 199 200 private class SafeSetIndeterminate 201 implements Runnable { 202 private boolean value; 203 public SafeSetIndeterminate(boolean value) { 204 this.value = value; 205 } 206 public void run() { 207 unsafeSetIndeterminate(value); 208 } 209 synchronized public void setState(boolean value) { 210 this.value = value; 211 } 212 } 213 214 private class SafeSetString 215 implements Runnable { 216 private String label = null; 217 public SafeSetString(String label) { 218 this.label = label; 219 } 220 public void run() { 221 unsafeSetString(label); 222 } 223 synchronized public void setLabel(String label) { 224 this.label = label; 225 } 226 } 227 228 private class SafeSetValue 229 implements Runnable { 230 private int value = -1; 231 public SafeSetValue(int value) { 232 this.value = value; 233 } 234 public void run() { 235 unsafeSetValue(value); 236 } 237 synchronized public void setValue(int value) { 238 this.value = value; 239 } 240 } 241 241 } 242 -
trunk/gli/src/org/greenstone/gatherer/gui/MenuBar.java
r4337 r4367 47 47 */ 48 48 public class MenuBar 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 49 extends JMenuBar { 50 /** The icon to be displayed alongside the context choosen help file. */ 51 private int current_tab = -1; 52 private JMenu file = null; 53 private JMenu edit = null; 54 private JMenu metadata = null; 55 private JMenu tools = null; 56 private JMenu log = null; 57 private JMenu window = null; 58 private JMenu source = null; 59 private JMenu level = null; 60 public JMenu help = null; 61 public JMenuItem file_associations; 62 public JMenuItem file_close = null; 63 public JMenuItem file_delete = null; 64 public JMenuItem file_exit = null; 65 public JMenuItem file_new = null; 66 public JMenuItem file_open = null; 67 public JMenuItem file_options = null; 68 public JMenuItem file_save = null; 69 public JMenuItem file_save_as; 70 public JMenuItem edit_copy; 71 public JMenuItem edit_cut; 72 public JMenuItem edit_paste; 73 public JMenuItem edit_undo = null; 74 public JMenuItem edit_redo = null; 75 public JMenuItem edit_replace = null; 76 public JMenuItem edit_search = null; 77 public JMenuItem metadata_add = null; 78 public JMenuItem metadata_edit = null; 79 public JMenuItem metadata_export = null; 80 public JMenuItem metadata_view = null; 81 public JMenuItem tools_log = null; 82 public JMenuItem tools_size = null; 83 public JMenuItem help_about; 84 public JMenuItem help_browse; 85 public JMenuItem help_build; 86 public JMenuItem help_collect; 87 public JMenuItem help_design; 88 public JMenuItem help_export; 89 public JMenuItem help_general; 90 public JMenuItem help_metaedit; 91 public JMenuItem help_mirror ; 92 public JMenuItem help_preview; 93 94 public MenuBar(MenuListener menu_listener) { 95 96 file = new JMenu(get("File")); 97 file.setMnemonic(KeyEvent.VK_F); 98 this.add(file); 99 100 file_associations = new JMenuItem(get("File_Associations"), KeyEvent.VK_A); 101 file_associations.addActionListener(Gatherer.g_man); 102 103 file_close = new JMenuItem(get("File_Close"), KeyEvent.VK_C); 104 file_close.addActionListener(Gatherer.g_man); 105 file_close.setEnabled(false); 106 107 file_delete = new JMenuItem(get("File_Delete"), KeyEvent.VK_D); 108 file_delete.addActionListener(Gatherer.g_man); 109 110 file_exit = new JMenuItem(get("File_Exit"), KeyEvent.VK_X); 111 file_exit.addActionListener(Gatherer.g_man); 112 113 file_new = new JMenuItem(get("File_New"), KeyEvent.VK_N); 114 file_new.addActionListener(Gatherer.g_man); 115 116 file_open = new JMenuItem(get("File_Open"), KeyEvent.VK_O); 117 file_open.addActionListener(Gatherer.g_man); 118 119 file_options = new JMenuItem(get("File_Options"), KeyEvent.VK_P); 120 file_options.addActionListener(Gatherer.g_man); 121 122 file_save = new JMenuItem(get("File_Save"), KeyEvent.VK_S); 123 file_save.addActionListener(Gatherer.g_man); 124 file_save.setEnabled(false); 125 126 file_save_as = new JMenuItem(get("File_Save_As"), KeyEvent.VK_A); 127 //file_save_as.addActionListener(Gatherer.g_man); 128 file_save_as.setEnabled(false); 129 130 // Layout file menu 131 file.add(file_new); 132 file.add(file_open); 133 file.add(file_save); 134 //file.add(file_save_as); 135 file.add(file_close); 136 //file.add(new JSeparator()); 137 //file.add(file_delete); 138 file.add(new JSeparator()); 139 file.add(file_associations); 140 file.add(file_options); 141 file.add(new JSeparator()); 142 file.add(file_exit); 143 144 // Edit menu 145 edit = new JMenu(get("Edit")); 146 edit.setMnemonic(KeyEvent.VK_E); 147 this.add(edit); 148 149 edit_copy = new JMenuItem(get("Edit_Copy") + " (ctrl-c)", KeyEvent.VK_C); 150 edit_copy.addActionListener(Gatherer.g_man); 151 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 152 edit_cut = new JMenuItem(get("Edit_Cut") + " (ctrl-x)", KeyEvent.VK_X); 153 edit_cut.addActionListener(Gatherer.g_man); 154 155 edit_paste = new JMenuItem(get("Edit_Paste") + " (ctrl-v)", KeyEvent.VK_V); 156 edit_paste.addActionListener(Gatherer.g_man); 157 158 edit_undo = new JMenuItem(get("Edit_Undo"), KeyEvent.VK_U); 159 edit_undo.setEnabled(false); 160 161 edit_redo = new JMenuItem(get("Edit_Redo"), KeyEvent.VK_D); 162 edit_redo.setEnabled(false); 163 164 edit_search = new JMenuItem(get("Edit_Search"), KeyEvent.VK_S); 165 edit_search.addActionListener(Gatherer.g_man); 166 167 edit_replace = new JMenuItem(get("Edit_Replace"), KeyEvent.VK_R); 168 edit_replace.addActionListener(Gatherer.g_man); 169 170 edit.add(edit_copy); 171 edit.add(edit_cut); 172 edit.add(edit_paste); 173 //edit.add(new JSeparator()); 174 //edit.add(edit_undo); 175 //edit.add(edit_redo); 176 edit.add(new JSeparator()); 177 edit.add(edit_search); 178 edit.add(edit_replace); 179 180 // Metadata menu 181 metadata = new JMenu(get("Metadata")); 182 metadata.setEnabled(false); 183 metadata.setMnemonic(KeyEvent.VK_M); 184 185 metadata_add = new JMenuItem(get("Metadata_Add"), KeyEvent.VK_A); 186 metadata_add.addActionListener(Gatherer.g_man); 187 188 metadata_edit = new JMenuItem(get("Metadata_Edit"), KeyEvent.VK_E); 189 metadata_edit.addActionListener(Gatherer.g_man); 190 191 metadata_export = new JMenuItem(get("Metadata_Export"), KeyEvent.VK_X); 192 metadata_export.addActionListener(Gatherer.g_man); 193 194 metadata_view = new JMenuItem(get("Metadata_View") + " " + get("FileActions.No_Selection"), KeyEvent.VK_V); 195 metadata_view.addActionListener(Gatherer.g_man); 196 197 metadata.add(metadata_add); 198 metadata.add(metadata_edit); 199 metadata.add(metadata_export); 200 metadata.add(metadata_view); 201 this.add(metadata); 202 203 // Tools menu 204 tools = new JMenu(get("Tools")); 205 206 tools_log = new JMenuItem(get("Tools_Log"), KeyEvent.VK_L); 207 tools_log.addActionListener(Gatherer.g_man); 208 209 tools_size = new JMenuItem("Calculate Record Size", KeyEvent.VK_S); 210 tools_size.addActionListener(Gatherer.g_man); 211 212 tools.add(tools_log); 213 tools.add(tools_size); 214 //this.add(tools); 215 216 // Help menu 217 help = new JMenu(get("Help")); 218 //help.addMenuListener(menu_listener); 219 help.setIcon(Utility.HELP_ICON); 220 221 help_about = new JMenuItem(get("Help_About")); 222 help_about.addActionListener(Gatherer.g_man); 223 224 help_browse = new JMenuItem(get("GUI.Browser"), Utility.BLANK_ICON); 225 help_browse.addActionListener(Gatherer.g_man); 226 227 help_build = new JMenuItem(get("GUI.Create"), Utility.BLANK_ICON); 228 help_build.addActionListener(Gatherer.g_man); 229 230 help_collect = new JMenuItem(get("GUI.Collection"), Utility.BLANK_ICON); 231 help_collect.addActionListener(Gatherer.g_man); 232 233 help_design = new JMenuItem(get("GUI.Build"), Utility.BLANK_ICON); 234 help_design.addActionListener(Gatherer.g_man); 235 236 help_export = new JMenuItem(get("GUI.Export"), Utility.BLANK_ICON); 237 help_export.addActionListener(Gatherer.g_man); 238 239 help_general = new JMenuItem(get("Source.General")); 240 help_general.addActionListener(Gatherer.g_man); 241 242 help_metaedit = new JMenuItem(get("GUI.MetaEdit"), Utility.BLANK_ICON); 243 help_metaedit.addActionListener(Gatherer.g_man); 244 245 help_mirror = new JMenuItem(get("GUI.Mirroring"), Utility.BLANK_ICON); 246 help_mirror.addActionListener(Gatherer.g_man); 247 248 help_preview = new JMenuItem(get("GUI.Preview"), Utility.BLANK_ICON); 249 help_preview.addActionListener(Gatherer.g_man); 250 251 // Layout help 252 help.add(help_general); 253 help.add(new JSeparator()); 254 if(Gatherer.config.get("workflow.browse", true)) { 255 help.add(help_browse); 256 } 257 if(Gatherer.config.get("workflow.mirror", true)) { 258 help.add(help_mirror); 259 } 260 if(Gatherer.config.get("workflow.gather", true)) { 261 help.add(help_collect); 262 } 263 if(Gatherer.config.get("workflow.enrich", true)) { 264 help.add(help_metaedit); 265 } 266 if(Gatherer.config.get("workflow.design", true)) { 267 help.add(help_design); 268 } 269 if(Gatherer.config.get("workflow.export", true)) { 270 help.add(help_export); 271 } 272 if(Gatherer.config.get("workflow.create", true)) { 273 help.add(help_build); 274 } 275 if(Gatherer.config.get("workflow.preview", true)) { 276 help.add(help_preview); 277 } 278 help.add(new JSeparator()); 279 help.add(help_about); 280 this.add(Box.createHorizontalGlue()); 281 this.add(help); 282 } 283 284 public void collectionChanged(boolean ready) { 285 file_close.setEnabled(ready); 286 file_save.setEnabled(ready); 287 file_save_as.setEnabled(ready); 288 metadata.setEnabled(ready); 289 tools.setEnabled(ready); 290 if(ready) { 291 Gatherer.c_man.undo.registerRedoSource(edit_redo); 292 Gatherer.c_man.undo.registerUndoSource(edit_undo); 293 } 294 } 295 296 public void setMetaAuditSuffix(String metaaudit_suffix) { 297 ///ystem.err.println("Set metadata view suffix: " + metaaudit_suffix); 298 metadata_view.setText(get("Menu.Metadata_View") + " " + metaaudit_suffix); 299 } 300 301 /** Set the enabled state of one of the help menu items, based on its 'tabs' current state. Note that this method should only be called from the AWTEvent thread. */ 302 public void tabEnabled(int tab_index, boolean state) { 303 JMenuItem selected = help.getItem(tab_index + 2); // Remember general and separator items 304 selected.setEnabled(state); 305 } 306 307 /** In order to provide context aware help advice we keep track of which 308 308 * tab the user has open, and then highlight that help menu item with 309 309 * separators. 310 310 * @param tab_index The index of the selected tab (0-7). 311 311 */ 312 313 314 312 public void tabSelected(int tab_index) { 313 JMenuItem selected; 314 if(current_tab != -1) { 315 315 // Remove the image 316 317 318 319 320 321 322 323 324 325 326 327 316 selected = help.getItem(current_tab); 317 if(selected != null) { 318 selected.setIcon(Utility.BLANK_ICON); 319 } 320 } 321 current_tab = tab_index + 2; 322 selected = help.getItem(current_tab); 323 if(selected != null) { 324 selected.setIcon(Utility.HELP_ICON); 325 } 326 selected = null; 327 } 328 328 329 329 /** Retrieves a key from the Dictionary, using no extra arguments. 330 330 * @param key A String which maps to a certain phrase from the Dictionary. 331 331 * @return The String the matches the key or an error String if no match 332 332 * found. 333 333 */ 334 335 336 337 338 334 private String get(String key) { 335 return get(key, null); 336 } 337 338 /** Retrieves a key from the Dictionary, providing extra arguments to 339 339 * be inserted using a String array. 340 340 * @param key A String which maps to a certain phrase from the Dictionary. … … 345 345 * found. 346 346 */ 347 348 349 350 351 352 353 354 355 347 private String get(String key, String args[]) { 348 if(key.indexOf('.') == -1) { 349 key = "Menu." + key; 350 } 351 return Gatherer.dictionary.get(key, args); 352 } 353 354 private class NonFocusMenu 355 extends JMenu { 356 356 public NonFocusMenu(String name) { 357 357 super(name); 358 358 setFocusPainted(false); 359 359 } … … 364 364 365 365 public void requestFocus(){ 366 366 } 367 367 368 368 public boolean requestFocus(boolean t){ 369 370 371 372 373 374 375 376 377 369 return false; 370 } 371 372 public void setFocusable(boolean f) { 373 } 374 } 375 376 private class NonFocusMenuItem 377 extends JMenuItem { 378 378 public NonFocusMenuItem(String name, int key) { 379 379 super(name, key); 380 380 setFocusPainted(false); 381 381 } … … 386 386 387 387 public void requestFocus(){ 388 388 } 389 389 390 390 public boolean requestFocus(boolean t){ 391 392 393 394 395 391 return false; 392 } 393 394 public void setFocusable(boolean f) { 395 } 396 396 397 397 } 398 398 } -
trunk/gli/src/org/greenstone/gatherer/gui/MetaEditPane.java
r4352 r4367 72 72 */ 73 73 public class MetaEditPane 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 74 extends JPanel 75 implements ActionListener, ListSelectionListener, TreeModelListener, TreeSelectionListener { 76 /** <i>true</i> if the selection has changed since the last time it was asked for, <i>false</i> otherwise. */ 77 public boolean has_changed = false; 78 /** The GValueTree graphically shows the available metadata that has been previously assigned, and provides controls for adding, updating and removing metadata, depending on the users selections in the other important components. */ 79 public GValueTree tree = null; 80 /** If only files are selected, then show folder is not available. */ 81 private boolean show_folder_enabled = false; 82 /** The layout manager used to display either the GTable (when records are selected) or a placeholder panel with the immortal words 'No Record Selected'. */ 83 private CardLayout card_layout = null; 84 /** The layout manager used to display either the GValueTree (when records are selected) or a placeholder panel with the immortal words 'No Record Selected'. */ 85 private CardLayout card_layout2 = null; 86 /** Used to dynamically filter the collection tree at user request. Note that this is synchronized with the collection tree filter in the Gather view. */ 87 private Filter filter = null; 88 /** The data model behind the GTable, to which we hold a reference for convenient access. */ 89 private GTableModel model = null; 90 /** The currently reported selection. Note that this may actually be incorrect, but if so the changed flag will be set, and the selection will be updated the next time it is needed. */ 91 private FileNode records[] = null; 92 /** Records which of the three GTable views is currently being shown, so we can determine what view to change to next (as they cycle). */ 93 //private int current_table_view; 94 /** The mode is determined by the metadata edit action choosen. */ 95 private int mode; 96 /** The button, which when clicked, adds metadata to the selected records. */ 97 private JButton add; 98 /** The button, which when clicked, removes the selected metadata from the selected records. */ 99 private JButton remove; 100 /** The button, which when clicked, changes the currently shown GTable view. */ 101 //private JButton table_view; 102 /** The button, which when clicked, updates the selected metadata from the selected records. */ 103 private JButton update; 104 /** The label at the top of the collection tree, which shows the collection name. */ 105 private JLabel collection_label; 106 /** The panel in which the metadata value card layout resides. */ 107 private JPanel control_pane; 108 /** The panel in which the metadata table card layout resides. */ 109 private JPanel table_card_pane; 110 /** The panel the table is added to. */ 111 private JPanel table_pane; 112 /** An icon showing the current state of the table build. */ 113 //private JProgressBar activity_bar; 114 /** The splitpane dividing the collection tree and the metadata based controls. */ 115 private JSplitPane external_split; 116 /** Divides the metadata table and the value tree controls. */ 117 private JSplitPane main_split_pane; 118 /** A reference to the metadata table, via its superclass. */ 119 private JTable table; 120 /** The label shown at the top of the metadata table detailing the current selection statistics. */ 121 private JTextField table_label; 122 /** The button to control whether assigned metadata is shown. */ 123 //private JToggleButton assigned_metadata_view; 124 /** The button to control whether unassigned metadata is shown. */ 125 //private JToggleButton unassigned_metadata_view; 126 /** A reference to the collection tree. */ 127 public DragTree collection_tree; 128 /** The currently selected metadata determined by listening to every second list selection event from the metadata table. */ 129 private Metadata selected_metadata; 130 /** Listens for right clicks over the collection tree. */ 131 private RightButtonListener right_button_listener = null; 132 /** A temporary storage array from Strings passed to the dictionary to be inserted in the phrase returned. */ 133 private String args[]; 134 /** Provide synchronization between the collection trees in this view and the collection pane view. */ 135 private TreeSynchronizer tree_sync = null; 136 static public Dimension BUTTON_SIZE = new Dimension(190, 25); 137 static private Dimension CONTROL_SIZE = new Dimension(560, 240); 138 static private Dimension LABEL_SIZE = new Dimension(75, 25); 139 static private Dimension MINIMUM_SIZE = new Dimension(100, 100); 140 static private Dimension TABLE_SIZE = new Dimension(560, 25); 141 static private Dimension TREE_SIZE = new Dimension(250, 500); 142 /** An element of the Mode type enumeration, indicating we are adding metadata (ie no metadata rows are selected in the metadata table). */ 143 static private int ADD = 0; 144 /** An element of the Mode type enumeration, indicating we are editing existing metadata (ie some row is selected in the metadata table). */ 145 static private int EDIT = 1; 146 /** The name of the panel containing the metadata table. */ 147 static final private String CARD_ONE = "Card One"; 148 /** The name of the panel containing the placeholder for the metadata table. */ 149 static final private String CARD_ZERO = "Card Zero"; 150 /** The name of the panel containing the placeholder for the value tree. */ 151 static final private String TOOLS_OFF = "Tools Off"; 152 /** The name of the panel containing the value tree. */ 153 static final private String TOOLS_ON = "Tools On"; 154 /** Constructor. 155 * @param tree_sync The <strong>TreeSynchronizer</strong> to be used on the collection tree. 156 * @see org.greenstone.gatherer.Configuration 157 * @see org.greenstone.gatherer.gui.table.GTable 158 * @see org.greenstone.gatherer.valuetree.GValueTree 159 */ 160 public MetaEditPane(TreeSynchronizer tree_sync) { 161 //this.current_table_view = GTableModel.SHOW_FILE; 162 this.tree = null; 163 this.tree_sync = tree_sync; 164 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 165 add = new JButton(get("MetaEditPrompt.Accumulate")); 166 add.addActionListener(this); 167 add.setEnabled(false); 168 add.setMnemonic(KeyEvent.VK_A); 169 add.setPreferredSize(BUTTON_SIZE); 170 171 update = new JButton(get("MetaEditPrompt.Overwrite")); 172 update.addActionListener(this); 173 update.setEnabled(false); 174 update.setMnemonic(KeyEvent.VK_P); 175 update.setPreferredSize(BUTTON_SIZE); 176 177 remove = new JButton(get("MetaEditPrompt.Remove")); 178 remove.addActionListener(this); 179 remove.setEnabled(false); 180 remove.setMnemonic(KeyEvent.VK_R); 181 remove.setPreferredSize(BUTTON_SIZE); 182 183 tree = new GValueTree(this, CONTROL_SIZE.width, CONTROL_SIZE.height, add, update, remove); 184 tree.setRootVisible(false); 185 } 186 /** Called whenever an action occurs on one of our registered buttons. 187 187 * @param event An <strong>ActionEvent</strong> containing information about the event. 188 188 * @see org.greenstone.gatherer.collection.CollectionManager … … 194 194 */ 195 195 public void actionPerformed(ActionEvent event) { 196 197 196 Object esrc = event.getSource(); 197 if(esrc == add) { 198 198 // Check the new metadata is valid 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 199 ElementWrapper element = tree.getSelectedMetadataElement(); 200 String value = tree.getSelectedValue(); 201 if(records != null && element != null && value != null) { 202 // Check the records, and if they are folders then display the warning. 203 if(!records[0].isLeaf()) { 204 WarningDialog dialog = new WarningDialog("warning.DirectoryLevelMetadata", true); 205 if(dialog.display() == JOptionPane.OK_OPTION) { 206 Gatherer.c_man.getCollection().msm.addMetadata(System.currentTimeMillis(), records, element, value); 207 } 208 dialog.dispose(); 209 dialog = null; 210 } 211 else { 212 Gatherer.c_man.getCollection().msm.addMetadata(System.currentTimeMillis(), records, element, value); 213 } 214 } 215 215 // Slight hack. Used to do this automatically if a value was added to the GValueModel, however this caused a Garbage Collection loop with the latest incarnation of FileQueue, so I've removed it and I'll manually call the value tree update here. 216 216 tree.valueChanged(new MSMEvent(this, 0, element, null, null)); 217 217 // Else bad metadata. 218 219 220 218 } 219 else if(esrc == update) { 220 System.err.println("MEP.Update!"); 221 221 // You can only update if there is a selected_metadata and 222 222 // you have valid values in all fields. 223 224 225 226 227 223 ElementWrapper element = tree.getSelectedMetadataElement(); 224 String value = tree.getSelectedValue(); 225 if(selected_metadata != null && records != null && element != null && value != null) { 226 selected_metadata = Gatherer.c_man.getCollection().msm.updateMetadata(System.currentTimeMillis(), selected_metadata, records, value, MetaEditPrompt.OVERWRITE, selected_metadata.isFileLevel()); 227 } 228 228 // Slight hack. Used to do this automatically if a value was added to the GValueModel, however this caused a Garbage Collection loop with the latest incarnation of FileQueue, so I've removed it and I'll manually call the value tree update here. 229 230 231 232 233 234 235 236 237 238 239 240 241 229 tree.valueChanged(new MSMEvent(this, 0, element, null, null)); 230 } 231 else if(esrc == remove) { 232 if(selected_metadata != null && records != null) { 233 Gatherer.c_man.getCollection().msm.removeMetadata(System.currentTimeMillis(), selected_metadata, records); 234 } 235 } 236 //else if(esrc == assigned_metadata_view || esrc == unassigned_metadata_view) { 237 // model.changeView(); 238 //} 239 validateControls(); 240 } 241 /** Some actions can only occur after this panel has been displayed on-screen, so this method is provided to do exactly that. Such actions include the proportioning of the split panes and the setting of table column widths. 242 242 * @see org.greenstone.gatherer.gui.table.GTableModel 243 243 */ 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 244 public void afterDisplay() { 245 external_split.setDividerLocation(0.3); 246 if(table != null) { 247 Dimension table_size = table.getPreferredSize(); 248 TableColumnModel column_model = table.getColumnModel(); 249 250 TableColumn inherited_column = column_model.getColumn(0); 251 inherited_column.setPreferredWidth(20); 252 inherited_column.setCellRenderer(new TableCellRenderer(model)); 253 254 TableColumn element_column = column_model.getColumn(1); 255 element_column.setPreferredWidth(table_size.width / 4); 256 element_column.setCellRenderer(new TableCellRenderer(model)); 257 258 TableColumn value_column = column_model.getColumn(2); 259 value_column.setPreferredWidth(((3 * table_size.width) / 4) - 15); 260 value_column.setCellRenderer(new TableCellRenderer(model)); 261 } 262 model.fireTableDataChanged(); 263 } 264 /** Called whenever a significant change has occured in the state of the currently loaded collection. 265 265 * @param ready <i>true</i> if there is a collection currently ready to be editing, <i>false</i> otherwise. 266 266 * @see org.greenstone.gatherer.collection.CollectionManager … … 269 269 * @see org.greenstone.gatherer.util.TreeSynchronizer 270 270 */ 271 272 273 274 275 276 271 public void collectionChanged(boolean ready) { 272 if(ready) { 273 TreeModel collection_model = Gatherer.c_man.getRecordSet(); 274 args = new String[1]; 275 args[0] = Gatherer.c_man.getCollection().getName(); 276 collection_label.setText(get("Collection.Collection", args)); 277 277 // Update label coloring. 278 279 280 278 collection_label.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false)); 279 collection_label.setForeground(Gatherer.config.getColor("coloring.collection_heading_foreground", false)); 280 collection_tree.setModel(collection_model); 281 281 // Update tree coloring. 282 283 282 collection_tree.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 283 collection_tree.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 284 284 // Register our msm dependant components (or correctly their models) with msm. 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 285 if(model != null) { 286 Gatherer.c_man.getCollection().msm.addMSMListener(model); 287 } 288 tree.setElementModel(Gatherer.c_man.getCollection().msm.getElementModel()); 289 } 290 else { 291 collection_label.setText(get("Collection.No_Collection")); 292 collection_label.setBackground(Color.lightGray); 293 collection_label.setForeground(Color.black); 294 collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(get("Collection.No_Collection")))); 295 } 296 297 filter.setEnabled(ready); 298 // Ensure that this collection tree view is synchronized with any others. 299 tree_sync.add(collection_tree); 300 } 301 /** Used to create, connect and layout the components to be shown on this control panel. 302 302 * @see org.greenstone.gatherer.Gatherer 303 303 * @see org.greenstone.gatherer.collection.CollectionManager … … 311 311 * @see org.greenstone.gatherer.valuetree.GValueTree 312 312 */ 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 313 public void display() { 314 right_button_listener = new RightButtonListener(); 315 // Creation 316 JPanel collection_pane = new JPanel(new BorderLayout()); 317 collection_pane.setMinimumSize(MINIMUM_SIZE); 318 collection_pane.setPreferredSize(TREE_SIZE); 319 320 external_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 321 322 ///atherer.println("\tCreating collection_label"); 323 args = new String[1]; 324 args[0] = get("Collection.No_Collection"); 325 collection_label = new JLabel(get("Collection.Collection")); 326 collection_label.setOpaque(true); 327 328 329 DragGroup group = new DragGroup(); 330 TreeModel collection_model = Gatherer.c_man.getRecordSet(); 331 if(collection_model != null) { 332 collection_tree = new DragTree("Collection", collection_model, null); 333 collection_model.addTreeModelListener(this); 334 } 335 else { 336 collection_tree = new DragTree("Collection", null); 337 } 338 group.add(collection_tree); 339 collection_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 340 collection_tree.putClientProperty("JTree.lineStyle", "Angled"); 341 collection_tree.addMouseListener(Gatherer.g_man.foa_listener); 342 collection_tree.addMouseListener(right_button_listener); 343 collection_tree.addTreeSelectionListener(this); 344 collection_tree.addTreeExpansionListener(Gatherer.g_man.foa_listener); 345 collection_tree.setLargeModel(true); 346 collection_tree.setRootVisible(false); 347 348 JScrollPane collection_scroll = new JScrollPane(collection_tree); 349 350 filter = Gatherer.g_man.getFilter(collection_tree); 351 filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false)); 352 // Change the default colours of this filters combobox. 353 GComboBox fcb = filter.getComboBox(); 354 fcb.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.collection_tree_background", false)); 355 fcb.setTextNonSelectionColor(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 356 fcb.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 357 fcb.setTextSelectionColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 358 fcb = null; 359 360 // Connection 361 362 // Layout 363 collection_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(3,3,3,3), BorderFactory.createLoweredBevelBorder())); 364 collection_pane.setMinimumSize(MINIMUM_SIZE); 365 collection_pane.setPreferredSize(new Dimension(Gatherer.g_man.getSize().width / 3, Gatherer.g_man.getSize().height)); 366 367 // Collection Pane 368 369 collection_pane.add(collection_label, BorderLayout.NORTH); 370 collection_pane.add(collection_scroll, BorderLayout.CENTER); 371 collection_pane.add(filter, BorderLayout.SOUTH); 372 373 // Main pane 374 //main_pane = new JPanel(new BorderLayout()); 375 //main_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 376 377 main_split_pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 378 main_split_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 379 main_split_pane.setDividerSize(8); 380 381 // Thumbnail - Currently disabled. 382 // At least until I figure out how to render thumbnails off screen, 383 // which possibly may happen with the discovery of CalpaHTML. 384 /* 385 thumbnail_pane = new JPanel(new BorderLayout()); 386 387 gatherer.debug("\tCreating thumbnail_label"); 388 thumbnail_label = new JLabel(get("Thumbnail")); 389 thumbnail_label.setHorizontalAlignment(JLabel.CENTER); 390 391 gatherer.debug("\tCreating thumbnail_view_pane"); 392 thumbnail_view_pane = new JPanel(new FlowLayout(FlowLayout.CENTER)); 393 thumbnail_scroll = new JScrollPane(thumbnail_view_pane); 394 395 thumbnail_pane.add(thumbnail_label, BorderLayout.NORTH); 396 thumbnail_pane.add(thumbnail_scroll, BorderLayout.CENTER); 397 */ 398 399 // Metadata Table. In order to achieve what Ian envisions I'm going 400 // to have to do a tricky. The table itself will sit in a stacked 401 // CardLayout. Card zero will be a see-through JPanel with a message 402 // smack bang in the center, something like "No Metadata". If any 403 // page of the table would appear to have no metadata this card will 404 // be swapped to the front. 405 406 table_pane = new JPanel(); 407 table_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0)); 408 409 JPanel table_title_pane = new JPanel(); 410 411 ///atherer.println("\tCreating metadata_label"); 412 table_label = new JTextField(get("No_File")); 413 table_label.setBackground(Color.white); 414 table_label.setEditable(false); 415 416 //activity_bar = new JProgressBar(); 417 //activity_bar.setPreferredSize(LABEL_SIZE); 418 //activity_bar.setString(get("Ready")); 419 //activity_bar.setStringPainted(true); 420 //activity_bar.setValue(activity_bar.getMaximum()); 421 422 card_layout = new CardLayout(); 423 424 table_card_pane = new JPanel(); 425 426 JPanel table_pane_zero = new JPanel(); 427 table_pane_zero.setOpaque(false); 428 429 JLabel no_file_message = new JLabel(get("No_File")); 430 no_file_message.setHorizontalAlignment(JLabel.CENTER); 431 no_file_message.setOpaque(false); 432 no_file_message.setVerticalAlignment(JLabel.CENTER); 433 434 JPanel table_pane_one = new JPanel(); 435 436 //JPanel view_pane = new JPanel(); 437 438 //JLabel view_label = new JLabel(get("View")); 439 //view_label.setPreferredSize(LABEL_SIZE); 440 441 //JPanel view_button_pane = new JPanel(); 442 443 //assigned_metadata_view = new JToggleButton(get("View_Assigned"), Utility.OFF_ICON); 444 //assigned_metadata_view.setSelectedIcon(Utility.ON_ICON); 445 //assigned_metadata_view.setSelected(true); 446 //assigned_metadata_view.addActionListener(this); 447 //unassigned_metadata_view = new JToggleButton(get("View_Unassigned"), Utility.OFF_ICON); 448 //unassigned_metadata_view.setSelectedIcon(Utility.ON_ICON); 449 //unassigned_metadata_view.setSelected(true); 450 //unassigned_metadata_view.addActionListener(this); 451 //XORToggleButtonGroup view_group = new XORToggleButtonGroup(); 452 //view_group.add(assigned_metadata_view); 453 //view_group.add(unassigned_metadata_view); 454 455 ///atherer.println("\tCreating metadata_table"); 456 table = new JTable(); 457 //model = new GTableModel(table, assigned_metadata_view, unassigned_metadata_view, activity_bar); 458 model = new GTableModel(table); 459 table.setModel(model); 460 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 461 table.getSelectionModel().addListSelectionListener(this); 462 table.setColumnSelectionAllowed(false); 463 464 // The default JTable doesn't quite have the desired properties - when a 465 // table cell is clicked on, the table is scrolled so the cell is as 466 // visible as possible. This means that the left-most cells can become 467 // hidden. To fix this, the MouseInputHandler in BasicTableUI is removed 468 // as a MouseListener on the table, and a very slightly altered copy is 469 // added in its place (TableMouseInputHandler). 470 MouseListener[] mls = table.getMouseListeners(); 471 for (int i = 0; i < mls.length; i++) { 472 // Remove the instances of MouseInputHandler 473 if (mls[i].toString().startsWith("javax.swing.plaf.basic.BasicTableUI$MouseInputHandler@")) { 474 table.removeMouseListener(mls[i]); 475 } 476 } 477 // Add the slightly-altered mouse listener 478 table.addMouseListener(new TableMouseInputHandler()); 479 480 JScrollPane table_scroll = new JScrollPane(table); 481 table_scroll.getViewport().setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 482 table_scroll.setOpaque(true); 483 484 // Control pane 485 ///atherer.println("\tCreating Metadata Controls"); 486 487 control_pane = new JPanel(); 488 control_pane.setBorder(BorderFactory.createLoweredBevelBorder()); 489 control_pane.setMinimumSize(MINIMUM_SIZE); 490 control_pane.setSize(CONTROL_SIZE); 491 control_pane.setPreferredSize(CONTROL_SIZE); 492 493 card_layout2 = new CardLayout(); 494 495 JPanel tools_off_pane = new JPanel(); 496 497 JLabel tools_off_label = new JLabel(get("No_Metadata_Element")); 498 tools_off_label.setHorizontalAlignment(JLabel.CENTER); 499 tools_off_label.setOpaque(false); 500 tools_off_label.setVerticalAlignment(JLabel.CENTER); 501 502 JPanel tools_on_pane = new JPanel(); 503 tools_on_pane.setMinimumSize(MINIMUM_SIZE); 504 tools_on_pane.setSize(TABLE_SIZE); 505 tools_on_pane.setPreferredSize(TABLE_SIZE); 506 507 // Layout. 508 509 // Metaedit controls 510 tools_off_pane.setLayout(new BorderLayout()); 511 tools_off_pane.add(tools_off_label, BorderLayout.CENTER); 512 513 tools_on_pane.setLayout(new BorderLayout()); 514 tools_on_pane.add(tree, BorderLayout.CENTER); 515 516 control_pane.setLayout(card_layout2); 517 control_pane.add(tools_off_pane, TOOLS_OFF); 518 control_pane.add(tools_on_pane, TOOLS_ON); 519 520 // Table components 521 table_title_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); 522 table_title_pane.setLayout(new BorderLayout()); 523 //table_title_pane.setLayout(new GridLayout(1,2,5,0)); 524 table_title_pane.add(table_label, BorderLayout.CENTER); 525 //table_title_pane.add(activity_bar); 526 527 table_pane_zero.setLayout(new BorderLayout()); 528 table_pane_zero.add(no_file_message, BorderLayout.CENTER); 529 530 table_pane_one.setLayout(new BorderLayout()); 531 table_pane_one.add(table_scroll, BorderLayout.CENTER); 532 533 table_card_pane.setLayout(card_layout); 534 table_card_pane.add(table_pane_zero, CARD_ZERO); 535 table_card_pane.add(table_pane_one, CARD_ONE); 536 537 //view_button_pane.setLayout(new GridLayout(1,2,5,0)); 538 //view_button_pane.add(assigned_metadata_view); 539 //view_button_pane.add(unassigned_metadata_view); 540 541 //view_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 542 //view_pane.setLayout(new BorderLayout()); 543 //view_pane.add(view_label, BorderLayout.WEST); 544 //view_pane.add(view_button_pane, BorderLayout.CENTER); 545 546 table_pane.setLayout(new BorderLayout()); 547 table_pane.add(table_title_pane, BorderLayout.NORTH); 548 table_pane.add(table_card_pane, BorderLayout.CENTER); 549 //table_pane.add(view_pane, BorderLayout.SOUTH); 550 551 //main_split_pane.add(control_pane, JSplitPane.TOP); 552 //main_split_pane.add(table_pane, JSplitPane.BOTTOM); 553 main_split_pane.add(table_pane, JSplitPane.TOP); 554 main_split_pane.add(control_pane, JSplitPane.BOTTOM); 555 main_split_pane.setDividerLocation(250); 556 557 external_split.add(collection_pane, JSplitPane.LEFT);//BorderLayout.WEST); 558 //this.add(main_pane, BorderLayout.CENTER); 559 external_split.add(main_split_pane, JSplitPane.RIGHT);//BorderLayout.CENTER); 560 561 this.setLayout(new BorderLayout()); 562 this.add(external_split, BorderLayout.CENTER); 563 } 564 /** Ensures a certain tree path is expanded, visible and selected within the collection tree. 565 565 * @param path The <strong>TreePath</strong> to make visible. 566 566 * @see org.greenstone.gatherer.tree.GTree 567 567 */ 568 569 570 571 572 568 public void expandPath(TreePath path) { 569 collection_tree.expandPath(path); 570 collection_tree.setSelectionPath(path); 571 } 572 /** Called to inform this control panel that it has just gained focus as an effect of the user clicking on its tab. 573 573 * @see org.greenstone.gatherer.tree.GTree 574 574 */ 575 576 577 578 579 580 575 public void gainFocus() { 576 // Use this opportunity to update the table model etc. 577 valueChanged(new TreeSelectionEvent(this, null, false, null, null)); 578 tree.setElementModel(Gatherer.c_man.getCollection().msm.getElementModel()); 579 } 580 /** Used to determine if this class contains a reference to an existing file record that matches the presumtively new record, and if one is found, returns it. Note that there is no need to search the metadata table model, as any file record that exists there must also exist in the records selection. 581 581 * @param new_record The <strong>FileNode</strong> which may or may not be the first occurance of a certain record. 582 582 * @return The matching <strong>FileNode</strong> if there is one, or <i>null</i>. 583 583 */ 584 585 586 587 588 589 590 591 592 593 594 584 public FileNode getAnyExistingRecord(FileNode new_record) { 585 FileNode match = null; 586 for(int i = 0; records != null && i < records.length && match == null; i++) { 587 if(records[i].equals(new_record)) { 588 match = records[i]; 589 } 590 } 591 return match; 592 } 593 594 /** Retrieve the currently selected records. 595 595 * @return A <strong>FileNode[]</strong> containing the current, and up to date, selection. 596 596 */ 597 597 public FileNode[] getSelectedNode() { 598 599 } 600 601 598 return records; 599 } 600 601 /** Retrieve the currently selected metadata. 602 602 * @return The <strong>Metadata</strong> in question. 603 603 */ 604 605 606 607 608 609 610 611 612 604 public Metadata getSelectedMetadata() { 605 return selected_metadata; 606 } 607 608 public void setSelection(File file) { 609 collection_tree.setSelection(file); 610 } 611 612 /** Determine the bounds of the selected metadata within the table, used during search and replace actions. 613 613 * @param metadata The <strong>Metadata</strong> to search for. 614 614 */ 615 616 617 618 619 620 621 622 623 615 public Rectangle setSelectedMetadata(Metadata metadata) { 616 return model.setSelectedMetadata(metadata); 617 } 618 619 public void refreshTrees() { 620 collection_tree.refresh(null); // Refresh entire tree. 621 } 622 623 /* Called when nodes have been modified, but the model hasn't changed. 624 624 * @param event Everything you ever wanted to know about model changes in one tidy <strong>TreeModelEvent</strong> package. 625 625 */ 626 627 628 629 630 626 public void treeNodesChanged(TreeModelEvent event) { 627 has_changed = true; 628 } 629 630 /* Called when nodes have been added to the model. 631 631 * @param event Everything you ever wanted to know about model changes in one tidy <strong>TreeModelEvent</strong> package. 632 632 */ 633 634 635 636 637 633 public void treeNodesInserted(TreeModelEvent event) { 634 has_changed = true; 635 } 636 637 /* Called when nodes have been removed from the model. 638 638 * @param event Everything you ever wanted to know about model changes in one tidy <strong>TreeModelEvent</strong> package. 639 639 */ 640 641 642 643 644 640 public void treeNodesRemoved(TreeModelEvent event) { 641 has_changed = true; 642 } 643 644 /** Called when nodes have been rearranged within the model. 645 645 * @param event Everything you ever wanted to know about model changes in one tidy <strong>TreeModelEvent</strong> package. 646 646 */ 647 648 649 650 647 public void treeStructureChanged(TreeModelEvent event) { 648 has_changed = true; 649 } 650 /** Called to ensure that if the tree model has changed in some way, the view has been updated. 651 651 * @see org.greenstone.gatherer.tree.GTree 652 652 */ 653 654 655 656 657 658 659 660 653 public void updateTree() { 654 if(has_changed) { 655 tree.updateUI(); 656 has_changed = false; 657 } 658 } 659 660 /** This method enables or diables the various controls based upon the state of the system. This method should be called after every change which could affect the GUI. 661 661 */ 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 662 public void validateControls() { 663 validateControls(true); 664 } 665 public void validateControls(boolean and_tree) { 666 validateMetadataTable(); 667 // Validate card_layout_2 668 if (selected_metadata != null) { 669 card_layout2.show(control_pane, TOOLS_ON); 670 } 671 else { 672 card_layout2.show(control_pane, TOOLS_OFF); 673 } 674 if(and_tree) { 675 tree.validateControls(); 676 } 677 } 678 679 /** Validate the metadata table area, and if no metadata is available display the no metadata panel. */ 680 public void validateMetadataTable() { 681 // Validate card_layout 682 if(records != null && model.getRowCount() > 0) { 683 card_layout.show(table_card_pane, CARD_ONE); 684 } 685 else { 686 card_layout.show(table_card_pane, CARD_ZERO); 687 } 688 } 689 690 /** Another in a long list of listeners, this one is called whenever the 691 691 * selection within the JTable changes. When it does we load the new data 692 692 * and set the selected_metadata if applicable (ie the metadata is non- … … 696 696 * @see org.greenstone.gatherer.valuetree.GValueTree 697 697 */ 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 698 public void valueChanged(ListSelectionEvent event) { 699 // We have a SINGLE_SELECTION model set so there is at most one 700 // selection. Get the offending row. 701 int selected = table.getSelectedRow(); 702 selected_metadata = model.getMetadataAtRow(selected); 703 if(selected_metadata != null) { // Check something is selected. 704 tree.setCommon(model.isCommon(selected)); 705 tree.setFileLevel(selected_metadata.isFileLevel()); 706 tree.setSelectedMetadataElement(selected_metadata.getElement()); 707 GValueNode value_node = selected_metadata.getValueNode(); 708 if(value_node != null) { 709 tree.setSelectedValue(value_node.getFullPath()); 710 } 711 else { 712 tree.setSelectedValue(""); 713 } 714 } 715 else { 716 card_layout2.show(control_pane, TOOLS_OFF); 717 } 718 } 719 720 /** This method is called whenever the selection within the collection 721 721 * tree changes. This causes the table to be rebuilt with a new model 722 722 * @param event A <strong>TreeSelectionEvent</strong> containing information about the event. … … 730 730 * @see org.greenstone.gatherer.util.ArrayTools 731 731 */ 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 732 public void valueChanged(TreeSelectionEvent event) { 733 ///ystem.err.print("We just detected a value changed event."); 734 if(Gatherer.g_man.getSelectedView() == this) { 735 if(collection_tree.getSelectionCount() > 0) { 736 records = null; 737 TreePath paths[] = collection_tree.getSelectionPaths(); 738 int files = 0; 739 int dirs = 0; 740 ///ystem.err.println("Selected " + paths.length + " files."); 741 for(int i = 0; i < paths.length; i++) { 742 FileNode record = (FileNode) paths[i].getLastPathComponent(); 743 records = ArrayTools.add(records, record); 744 } 745 746 table_label.setText(collection_tree.getSelectionDetails()); 747 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 748 // Remove old model from msm 749 Gatherer.c_man.getCollection().msm.removeMSMListener(model); 750 // Create new model (which will add itself to msm). 751 //model = new GTableModel(table, assigned_metadata_view, unassigned_metadata_view, activity_bar, records); 752 model = new GTableModel(table, records); 753 table.setModel(model); 754 } 755 else { 756 ///ystem.err.println("No node selected!"); 757 records = null; 758 // Remove old model from msm 759 if(Gatherer.c_man.ready()) { 760 Gatherer.c_man.getCollection().msm.removeMSMListener(model); 761 } 762 // Create new model (which will add itself to msm). 763 //model = new GTableModel(table, assigned_metadata_view, unassigned_metadata_view, activity_bar); 764 model = new GTableModel(table); 765 table.setModel(model); 766 } 767 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 768 if(table != null) { 769 Dimension table_size = table.getPreferredSize(); 770 TableColumnModel column_model = table.getColumnModel(); 771 772 TableColumn inherited_column = column_model.getColumn(0); 773 inherited_column.setPreferredWidth(20); 774 inherited_column.setCellRenderer(new TableCellRenderer(model)); 775 775 776 777 778 776 TableColumn element_column = column_model.getColumn(1); 777 element_column.setPreferredWidth(TABLE_SIZE.width / 4); 778 element_column.setCellRenderer(new TableCellRenderer(model)); 779 779 780 781 782 783 784 785 786 787 780 TableColumn value_column = column_model.getColumn(2); 781 value_column.setPreferredWidth(((3 * TABLE_SIZE.width) / 4) - 15); 782 value_column.setCellRenderer(new TableCellRenderer(model)); 783 } 784 validateControls(); 785 } 786 } 787 /** Retrieve a phrase from the Dictionary based on the given key. 788 788 * @param key The <strong>String</strong> which maps to the phrase to retrieve. 789 789 * @return The desired phrase as a <strong>String</strong>, or possibly an error message if no such phrase exists. 790 790 */ 791 792 793 794 791 private String get(String key) { 792 return get(key, null); 793 } 794 /** Retrieve a phrase from the Dictionary based on the given key and filled in with the given arguments. 795 795 * @param key The <strong>String</strong> which maps to the phrase to retrieve. 796 796 * @param args A <strong>String[]</strong> of arguments to be inserted in the phrase. … … 800 800 */ 801 801 private String get(String key, String args[]) { 802 803 804 805 802 if(key.indexOf('.') == -1) { 803 key = "MetaEdit." + key; 804 } 805 return Gatherer.dictionary.get(key,args); 806 806 } 807 807 … … 824 824 Point p2 = SwingUtilities.convertPoint(table, p, editorComponent); 825 825 dispatchComponent = SwingUtilities.getDeepestComponentAt(editorComponent, 826 826 p2.x, p2.y); 827 827 } 828 828 … … 936 936 937 937 938 /** A listener for right mouse button clicks over the collection tree. */ 939 private class RightButtonListener 940 extends MouseAdapter { 941 /** Called whenever a mouse click occurs (right or left) over a target component. 942 * @param event A <strong>MouseEvent</strong> containing further information about the mouse click action. 943 * @see org.greenstone.gatherer.gui.MetaEditPane.RightButtonMenu 938 /** A listener for right mouse button clicks over the collection tree. */ 939 private class RightButtonListener 940 extends MouseAdapter { 941 /** Called whenever a mouse click occurs (right or left) over a target component. 942 * @param event A <strong>MouseEvent</strong> containing further information about the mouse click action. 943 * @see org.greenstone.gatherer.gui.MetaEditPane.RightButtonMenu 944 */ 945 public void mouseClicked(MouseEvent event) { 946 if(SwingUtilities.isRightMouseButton(event)) { 947 new RightButtonMenu(event); 948 } 949 } 950 } 951 /** Provides a popup menu to display when a right mouse button click is detected over the collection tree. */ 952 private class RightButtonMenu 953 extends JPopupMenu 954 implements ActionListener { 955 /** Constructor. 956 * @param event The <strong>MouseEvent</strong> that triggered the creation of this menu. Used to determine where the menu will be located. 944 957 */ 945 public void mouseClicked(MouseEvent event) { 946 if(SwingUtilities.isRightMouseButton(event)) { 947 new RightButtonMenu(event); 948 } 949 } 950 } 951 /** Provides a popup menu to display when a right mouse button click is detected over the collection tree. */ 952 private class RightButtonMenu 953 extends JPopupMenu 954 implements ActionListener { 955 /** Constructor. 956 * @param event The <strong>MouseEvent</strong> that triggered the creation of this menu. Used to determine where the menu will be located. 957 */ 958 public RightButtonMenu(MouseEvent event) { 959 super(); 958 public RightButtonMenu(MouseEvent event) { 959 super(); 960 960 // Creation 961 962 963 961 JMenuItem show_metaaudit = new JMenuItem(get("Menu.Metadata_View") + " " + collection_tree.getSelectionDetails(), KeyEvent.VK_V); 962 show_metaaudit.addActionListener(this); 963 add(show_metaaudit); 964 964 // Display 965 966 967 968 969 970 965 show(collection_tree, event.getX(), event.getY()); 966 show_metaaudit = null; 967 args = null; 968 969 } 970 /** Called whenever a user clicks on the single menu item, view all assigned metadata. 971 971 * @param event An <strong>ActionEvent</strong> containing further information about the action. 972 972 * @see org.greenstone.gatherer.Gatherer 973 973 * @see org.greenstone.gatherer.gui.GUIManager 974 974 */ 975 public void actionPerformed(ActionEvent event) { 976 Gatherer.g_man.showMetaAuditBox(); 977 } 978 } 979 975 public void actionPerformed(ActionEvent event) { 976 Gatherer.g_man.showMetaAuditBox(); 977 } 978 } 980 979 } 981 982 983 984 -
trunk/gli/src/org/greenstone/gatherer/gui/MetaEditPrompt.java
r4353 r4367 36 36 /** Displays a dynamic prompt to allow the user to choose how metadata is to be added, updated or removed from target FileNodes. The prompt changes depending on the action requested, the file nodes encountered and the number of file nodes in the selection. */ 37 37 public class MetaEditPrompt 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 38 extends JDialog 39 implements ActionListener { 40 41 private int value; 42 private JButton accumulate; 43 private JButton accumulate_all; 44 private JButton cancel; 45 private JButton skip; 46 private JButton overwrite; 47 private JButton overwrite_all; 48 private JButton remove; 49 private JButton remove_all; 50 private JButton update; 51 private JButton update_all; 52 static private Dimension LABEL_SIZE = new Dimension(100, 25); 53 static private Dimension SIZE = new Dimension(400, 280); 54 // Generic prompt values. 55 static public int CONFIRM = 0; 56 static public int CANCEL = 1; 57 static public int SKIP = 2; 58 // Values for the different add and update action prompts. 59 static public int ACCUMULATE = 3; 60 static public int ACCUMULATE_ALL = 4; 61 static public int OVERWRITE = 5; 62 static public int OVERWRITE_ALL = 6; 63 static public int UPDATE_ONCE = 7; // Caused by SARM 64 // Values for the different remove action prompts. 65 static public int REMOVE = 8; 66 static public int REMOVE_ALL = 9; 67 // Prompt Types 68 static public String ADD_PROMPT = "Add_Prompt"; 69 static public String REMOVE_PROMPT = "Remove_Prompt"; 70 static public String UPDATE_PROMPT = "Overwrite_Prompt"; 71 72 public MetaEditPrompt(String type, boolean multiple_selection, File file, String element, String current_value, String new_value) { 73 super(Gatherer.g_man, true); // Needed for modal response! 74 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 75 // Setup 76 this.setSize(SIZE); 77 this.setTitle(get("MetaEditPrompt.Title")); 78 79 // Creation 80 JPanel content_pane = (JPanel)this.getContentPane(); 81 JLabel title_label = new JLabel(get("MetaEditPrompt." + type)); 82 83 JPanel details_pane = new JPanel(); 84 JPanel filename_panel = new JPanel(); 85 JLabel filename_label = new JLabel(get("MetaEditPrompt.File")); 86 filename_label.setPreferredSize(LABEL_SIZE); 87 TextFieldLabel filename_field = new TextFieldLabel(Utility.trimCenter(file.getAbsolutePath(), 40)); 88 filename_field.setFont(Gatherer.config.getFont("general.tooltip_font", false)); 89 JPanel element_panel = new JPanel(); 90 JLabel element_label = new JLabel(get("MetaEditPrompt.Element")); 91 element_label.setPreferredSize(LABEL_SIZE); 92 TextFieldLabel element_field = new TextFieldLabel(element); 93 JPanel current_value_panel = new JPanel(); 94 JLabel current_value_label = new JLabel(get("MetaEditPrompt.Current_Value")); 95 current_value_label.setPreferredSize(LABEL_SIZE); 96 TextFieldLabel current_value_field = new TextFieldLabel(current_value); 97 JPanel new_value_panel = new JPanel(); 98 JLabel new_value_label = new JLabel(get("MetaEditPrompt.New_Value")); 99 new_value_label.setPreferredSize(LABEL_SIZE); 100 TextFieldLabel new_value_field = new TextFieldLabel(new_value, (type == ADD_PROMPT || type == UPDATE_PROMPT)); 101 102 JPanel buttons_pane = new JPanel(); 103 accumulate = new JButton(get("MetaEditPrompt.Accumulate")); 104 accumulate.setEnabled(type == ADD_PROMPT); 105 accumulate.setMnemonic(KeyEvent.VK_A); 106 accumulate_all = new JButton(get("MetaEditPrompt.Accumulate_All")); 107 accumulate_all.setEnabled(type == ADD_PROMPT && multiple_selection); 108 accumulate_all.setMnemonic(KeyEvent.VK_L); 109 cancel = new JButton(get("MetaEditPrompt.Cancel")); 110 cancel.setMnemonic(KeyEvent.VK_C); 111 skip = new JButton(get("MetaEditPrompt.Skip")); 112 skip.setEnabled(multiple_selection); 113 skip.setMnemonic(KeyEvent.VK_S); 114 overwrite = new JButton(get("MetaEditPrompt.Overwrite")); 115 overwrite.setEnabled(type == UPDATE_PROMPT); 116 overwrite.setMnemonic(KeyEvent.VK_R); 117 overwrite_all = new JButton(get("MetaEditPrompt.Overwrite_All")); 118 overwrite_all.setEnabled(type == UPDATE_PROMPT && multiple_selection); 119 overwrite_all.setMnemonic(KeyEvent.VK_P); 120 remove = new JButton(get("MetaEditPrompt.Remove")); 121 remove.setEnabled(type == REMOVE_PROMPT); 122 remove.setMnemonic(KeyEvent.VK_R); 123 remove_all = new JButton(get("MetaEditPrompt.Remove_All")); 124 remove_all.setEnabled(type == REMOVE_PROMPT && multiple_selection); 125 remove_all.setMnemonic(KeyEvent.VK_A); 126 127 // Connection 128 accumulate.addActionListener(this); 129 accumulate_all.addActionListener(this); 130 cancel.addActionListener(this); 131 overwrite.addActionListener(this); 132 overwrite_all.addActionListener(this); 133 remove.addActionListener(this); 134 remove_all.addActionListener(this); 135 skip.addActionListener(this); 136 137 // Layout 138 title_label.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 139 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 140 filename_panel.setLayout(new BorderLayout()); 141 filename_panel.add(filename_label, BorderLayout.WEST); 142 filename_panel.add(filename_field, BorderLayout.CENTER); 143 144 element_panel.setLayout(new BorderLayout()); 145 element_panel.add(element_label, BorderLayout.WEST); 146 element_panel.add(element_field, BorderLayout.CENTER); 147 148 current_value_panel.setLayout(new BorderLayout()); 149 current_value_panel.add(current_value_label, BorderLayout.WEST); 150 current_value_panel.add(current_value_field, BorderLayout.CENTER); 151 152 new_value_panel.setLayout(new BorderLayout()); 153 new_value_panel.add(new_value_label, BorderLayout.WEST); 154 new_value_panel.add(new_value_field, BorderLayout.CENTER); 155 156 details_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 157 details_pane.setLayout(new GridLayout(4,1,0,4)); 158 details_pane.add(filename_panel); 159 details_pane.add(element_panel); 160 details_pane.add(current_value_panel); 161 details_pane.add(new_value_panel); 162 163 buttons_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 164 buttons_pane.setLayout(new GridLayout(4,2,0,0)); 165 buttons_pane.add(accumulate); 166 buttons_pane.add(accumulate_all); 167 buttons_pane.add(overwrite); 168 buttons_pane.add(overwrite_all); 169 buttons_pane.add(remove); 170 buttons_pane.add(remove_all); 171 buttons_pane.add(skip); 172 buttons_pane.add(cancel); 173 174 content_pane.setBorder(BorderFactory.createEmptyBorder(3,3,3,3)); 175 content_pane.setLayout(new BorderLayout()); 176 content_pane.add(title_label, BorderLayout.NORTH); 177 content_pane.add(details_pane, BorderLayout.CENTER); 178 content_pane.add(buttons_pane, BorderLayout.SOUTH); 179 180 // Position 181 Rectangle frame_bounds = Gatherer.g_man.getBounds(); 182 this.setLocation(frame_bounds.x + ((frame_bounds.width - SIZE.width) / 2), frame_bounds.y + ((frame_bounds.height - SIZE.height) / 2)); 183 } 184 185 public void actionPerformed(ActionEvent event) { 186 Object esrc = event.getSource(); 187 if(esrc == accumulate) { 188 value = ACCUMULATE; 189 } 190 else if(esrc == accumulate_all) { 191 value = ACCUMULATE_ALL; 192 } 193 else if(esrc == cancel) { 194 value = CANCEL; 195 } 196 else if(esrc == skip) { 197 value = SKIP; 198 } 199 else if(esrc == overwrite) { 200 value = OVERWRITE; 201 } 202 else if(esrc == overwrite_all) { 203 value = OVERWRITE_ALL; 204 } 205 else if(esrc == remove) { 206 value = REMOVE; 207 } 208 else if(esrc == remove_all) { 209 value = REMOVE_ALL; 210 } 211 this.dispose(); 212 } 213 214 public int display() { 215 show(); 216 return value; 217 } 218 219 private String get(String key) { 220 return Gatherer.dictionary.get(key); 221 } 222 222 } -
trunk/gli/src/org/greenstone/gatherer/gui/MirrorPane.java
r4293 r4367 58 58 */ 59 59 public class MirrorPane 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 60 extends JPanel 61 implements ActionListener { 62 63 private ButtonGroup destination_folder_options; 64 private DragTree workspace_tree = null; 65 private FileSystemModel model = null; 66 /** The filter currently applied to the workspace tree. */ 67 private Filter workspace_filter = null; 68 69 private ImageIcon thumbnail; 70 71 private JButton download; 72 private JButton view_selector; 73 74 private JCheckBox download_hidden; 75 private JCheckBox higher_directories; 76 private JCheckBox infinite; 77 private JCheckBox overwrite_existing; 78 private JCheckBox remove_failed; 79 private JCheckBox same_host; 80 81 private JScrollPane list_scroll; 82 private JScrollPane workspace_scroll; 83 84 private JTextField download_depth; 85 private JTextField number_downloads; 86 private JTextField number_each_host; 87 private JTextField source_url; 88 89 private JToggleButton destination_private; 90 private JToggleButton destination_shared; 91 92 93 /** Ensures that expansion and selection events between workspace trees based on the same model are synchronized. */ 94 private TreeSynchronizer tree_sync = null; 95 /** A reference to the object that provides JNI ability. */ 96 private WGet getter; 97 /** The default size of a label in the interface. */ 98 static final private Dimension LABEL_SIZE = new Dimension(100,30); 99 /** The default size of the tree in the interface. */ 100 static final private Dimension TREE_SIZE = new Dimension(250, 430); 101 102 public MirrorPane(TreeSynchronizer workspace_tree_sync) { 103 this.tree_sync = workspace_tree_sync; 104 getter = new WGet(); 105 getter.start(); 106 } 107 108 public void actionPerformed(ActionEvent event) { 109 Object event_source = event.getSource(); 110 if(event_source == download) { 111 111 // Check we have a valid url. 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 112 GURL target_gurl = new GURL(source_url.getText()); 113 if(target_gurl.getURL() != null) { 114 // Update configuration settings. 115 Gatherer.config.set("mirroring.page_requisites", false, download_hidden.isSelected()); 116 Gatherer.config.set("mirroring.no_parents", false, !higher_directories.isSelected()); 117 Gatherer.config.set("mirroring.clobber", false, overwrite_existing.isSelected()); 118 Gatherer.config.set("mirroring.remove_failed", false, remove_failed.isSelected()); 119 Gatherer.config.set("mirroring.other_hosts", false, !same_host.isSelected()); 120 // Depth 121 if(infinite.isSelected()) { 122 Gatherer.config.setInt("mirroring.depth", false, -1); 123 } 124 else if(download_depth.getText().length() > 0){ 125 //Gatherer.println("Download_depth = " + download_depth.getText().trim()); 126 Gatherer.config.setInt("mirroring.depth", false, Integer.parseInt(download_depth.getText().trim())); 127 } 128 129 // Queue download 130 if(destination_shared.isSelected()) { 131 getter.newJob(new GURL(source_url.getText()), model, Utility.CACHE_DIR); 132 } 133 else { 134 getter.newJob(new GURL(source_url.getText()), model, Gatherer.c_man.getCollectionCache()); 135 } 136 } 137 137 // Otherwise indicate to the user that they've done something 138 138 // wrong. 139 140 141 142 143 144 145 146 147 148 149 139 else { 140 // Error message box. 141 String args[] = new String[1]; 142 args[0] = source_url.getText(); 143 message(Message.ERROR, get("Malformed_URL", args)); 144 // Colour source_url red 145 source_url.setForeground(Color.red); 146 } 147 148 } 149 else if(event_source == source_url) { 150 150 // They've typed something. Change colour back to black 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 151 source_url.setForeground(Color.black); 152 } 153 } 154 155 public void collectionChanged(boolean ready) { 156 // Some buttons are only enabled if a collection is open. 157 if(ready) { 158 destination_private.setEnabled(true); 159 } 160 else { 161 destination_shared.setSelected(true); 162 destination_private.setEnabled(false); 163 } 164 // Retrieve appropriate workspace 165 model = (FileSystemModel) Gatherer.c_man.getWorkspace(); 166 workspace_tree.setModel(model); 167 tree_sync.add(workspace_tree); 168 } 169 170 public void display() { 171 this.setLayout(new BorderLayout()); 172 173 // Create 174 JPanel tree_pane = new JPanel(new BorderLayout()); 175 tree_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 176 tree_pane.setMinimumSize(TREE_SIZE); 177 tree_pane.setSize(TREE_SIZE); 178 tree_pane.setPreferredSize(TREE_SIZE); 179 180 //Gatherer.println("\tCreating tree_label"); 181 JLabel tree_label = new JLabel(get("Workspace_Tree")); 182 183 //Gatherer.println("\tCreating public tree"); 184 model = (FileSystemModel) Gatherer.c_man.getWorkspace(); 185 workspace_tree = new DragTree("Workspace_Mirror", model, null); 186 workspace_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 187 workspace_tree.putClientProperty("JTree.lineStyle", "Angled"); 188 workspace_tree.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_background", false)); 189 workspace_tree.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 190 workspace_tree.setRootVisible(false); 191 workspace_tree.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_background", false)); 192 workspace_tree.setTextSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_foreground", false)); 193 194 // Add to a dummy drag-group. 195 DragGroup group = new DragGroup(); 196 group.add(workspace_tree); 197 group = null; 198 199 workspace_filter = Gatherer.g_man.getFilter(workspace_tree); 200 workspace_filter.setBackground(Gatherer.config.getColor("coloring.workspace_heading_background", false)); 201 // Change the default colours of this filters combobox. 202 GComboBox fcb = workspace_filter.getComboBox(); 203 fcb.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_background", false)); 204 fcb.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 205 fcb.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_background", false)); 206 fcb.setTextSelectionColor(Gatherer.config.getColor("coloring.workspace_selection_foreground", false)); 207 fcb = null; 208 209 tree_pane.add(tree_label, BorderLayout.NORTH); 210 tree_pane.add(new JScrollPane(workspace_tree), BorderLayout.CENTER); 211 tree_pane.add(workspace_filter, BorderLayout.SOUTH); 212 213 // Create control_pane 214 JPanel control_pane = new JPanel(new BorderLayout()); 215 216 //Gatherer.println("\tCreating control_label"); 217 JLabel control_label = new JLabel(get("Download_Controls")); 218 control_label.setHorizontalAlignment(JLabel.CENTER); 219 control_label.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 220 221 //central_pane = new JPanel(new GridLayout(7,1)); 222 JPanel central_pane = new JPanel(); 223 central_pane.setLayout(new BoxLayout(central_pane, BoxLayout.Y_AXIS)); 224 225 //Gatherer.println("\tCreating source_url_pane"); 226 JPanel source_url_pane = new JPanel(new BorderLayout()); 227 JLabel source_url_label = new JLabel(get("Source_URL")); 228 source_url_label.setPreferredSize(LABEL_SIZE); 229 source_url = new JTextField(""); 230 source_url_pane.add(source_url_label, BorderLayout.WEST); 231 source_url_pane.add(source_url, BorderLayout.CENTER); 232 233 234 //Gatherer.println("\tCreating download_depth"); 235 JPanel download_depth_pane = new JPanel(new FlowLayout(FlowLayout.LEFT)); 236 JLabel download_depth_label = new JLabel(get("Download_Depth")); 237 // Default depth. Its an int so we'll do some magic handwaving to magic it into a String. Alakazam. 238 download_depth = new JTextField(Utility.getDepthString(6)); 239 infinite = new JCheckBox("Infinite"); 240 download_depth_pane.add(download_depth_label); 241 download_depth_pane.add(download_depth); 242 download_depth_pane.add(infinite); 243 244 //Gatherer.println("\tCreating destination_folder"); 245 JPanel destination_folder_pane = new JPanel(new FlowLayout(FlowLayout.LEFT)); 246 JLabel destination_folder_label = new JLabel(get("Destination_Folder")); 247 destination_folder_options = new ButtonGroup(); 248 destination_private = new JToggleButton(get("Destination_Private")); 249 destination_private.setEnabled(Gatherer.c_man != null && Gatherer.c_man.ready()); 250 destination_private.setIcon(Utility.OFF_ICON); 251 destination_private.setSelectedIcon(Utility.ON_ICON); 252 destination_private.setSelected(false); 253 destination_private.addActionListener(this); 254 destination_folder_options.add(destination_private); 255 destination_shared = new JToggleButton(get("Destination_Shared")); 256 destination_shared.setIcon(Utility.OFF_ICON); 257 destination_shared.setSelectedIcon(Utility.ON_ICON); 258 destination_shared.setSelected(true); 259 destination_shared.addActionListener(this); 260 destination_folder_options.add(destination_shared); 261 destination_folder_pane.add(destination_folder_label); 262 destination_folder_pane.add(destination_private); 263 destination_folder_pane.add(destination_shared); 264 265 //Gatherer.println("\tCreating download_hidden"); 266 download_hidden = new JCheckBox(get("Download_Hidden")); 267 // Why the friken heil is the horizontal alignment called Y? 268 download_hidden.setAlignmentY(Component.LEFT_ALIGNMENT); 269 download_hidden.setSelected(Gatherer.config.get("mirroring.page_requisites", false)); 270 271 //Gatherer.println("\tCreating higher_directories"); 272 higher_directories = new JCheckBox(get("Higher_Directories")); 273 higher_directories.setSelected(!Gatherer.config.get("mirroring.no_parents", false)); 274 275 //Gatherer.println("\tCreating same_host"); 276 same_host = new JCheckBox(get("Same_Host")); 277 same_host.setSelected(!Gatherer.config.get("mirroring.other_hosts", false)); 278 279 //Gatherer.println("\tCreating overwrite"); 280 overwrite_existing = new JCheckBox(get("Overwrite_Existing")); 281 overwrite_existing.setSelected(Gatherer.config.get("mirroring.overwrite", false)); 282 283 JLabel further_options = new JLabel(get("Further_Options")); 284 further_options.setHorizontalAlignment(JLabel.LEFT); 285 286 central_pane.add(source_url_pane); 287 central_pane.add(download_depth_pane); 288 central_pane.add(destination_folder_pane); 289 290 JPanel three_mid = new JPanel(new GridLayout(5,1)); 291 292 three_mid.add(download_hidden); 293 three_mid.add(higher_directories); 294 three_mid.add(same_host); 295 three_mid.add(overwrite_existing); 296 three_mid.add(further_options); 297 298 central_pane.add(three_mid); 299 300 //Gatherer.println("\tCreating thumbnail"); 301 thumbnail = new ImageIcon(Utility.RES_DIR + "no_thumbnail.gif"); 302 JLabel thumbnail_holder = new JLabel(thumbnail); 303 // Default thumbnail size. 304 //thumbnail_holder.setSize(Gatherer.config.getDimension("mirroring.thumbnail_size", false)); 305 thumbnail_holder.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 306 307 JPanel lower_pane = new JPanel(new BorderLayout()); 308 lower_pane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED), get("Download_List_Configuration"))); 309 310 remove_failed = new JCheckBox(get("Remove_Failed")); 311 remove_failed.setSelected(Gatherer.config.get("mirroring.remove_failed", false)); 312 313 //Gatherer.println("\tCreating download_button"); 314 download = new JButton(get("Download")); 315 download.addActionListener(this); 316 download.setHorizontalAlignment(JLabel.CENTER); 317 JPanel download_pane = new JPanel(new BorderLayout()); 318 319 lower_pane.add(remove_failed, BorderLayout.NORTH); 320 lower_pane.add(download_pane, BorderLayout.CENTER); 321 322 control_pane.add(control_label, BorderLayout.NORTH); 323 control_pane.add(central_pane, BorderLayout.WEST); 324 //control_pane.add(thumbnail_holder, BorderLayout.CENTER); 325 control_pane.add(lower_pane, BorderLayout.SOUTH); 326 327 // Create list_pane 328 JPanel list_pane = new JPanel(new BorderLayout()); 329 list_pane.setPreferredSize(new Dimension(Gatherer.g_man.getSize().width, Gatherer.g_man.getSize().height / 4)); 330 331 download_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 332 download_pane.add(download); 333 334 //Gatherer.println("\tCreating list"); 335 list_scroll = getter.getJobList(); 336 337 //list_pane.add(download_pane, BorderLayout.NORTH); 338 list_pane.add(list_scroll, BorderLayout.CENTER); 339 340 // Add to content 341 JPanel temp_pane = new JPanel(new BorderLayout()); 342 this.add(tree_pane, BorderLayout.WEST); 343 this.add(control_pane, BorderLayout.CENTER); 344 //temp_pane.add(control_pane, BorderLayout.NORTH); 345 //temp_pane.add(list_pane, BorderLayout.CENTER); 346 this.add(list_pane, BorderLayout.SOUTH); 347 } 348 349 public void setURL(String url) { 350 source_url.setText(url); 351 } 352 353 private String get(String key) { 354 return get(key, null); 355 } 356 357 private String get(String key, String args[]) { 358 if(key.indexOf('.') == -1) { 359 key = "Mirroring." + key; 360 } 361 return Gatherer.dictionary.get(key,args); 362 } 363 364 /** Creates and dispatches a message given the initial details. 365 * @param level An int indicating the message level for this message. 366 * @param message A String which contains the payload of this message. 367 */ 368 private void message(int level, String message) { 369 Message msg = new Message(Message.MIRRORING, level, message); 370 if(Gatherer.g_man != null) { 371 Gatherer.g_man.message_pane.show(msg); 372 } else { 373 Gatherer.println(msg.toString()); 374 } 375 } 376 376 } -
trunk/gli/src/org/greenstone/gatherer/gui/NewCollectionDetailsPrompt.java
r4355 r4367 13 13 14 14 public class NewCollectionDetailsPrompt 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 15 extends JDialog { 16 private boolean cancelled; 17 private File base_final; 18 private JButton create_button; 19 private JComboBox base_collection; 20 private JDialog self; 21 private JTextArea description; 22 private JTextField address; 23 private JTextField host; 24 private JTextField title; 25 private RestrictedTextField file; 26 private String description_final; 27 private String email_final; 28 private String name_final; 29 private String title_final; 30 static private Dimension label_size = new Dimension(230, 25); 31 /** The size of this new collection dialog box. */ 32 static private Dimension size = new Dimension(700, 350); 33 static private int FILENAME_SIZE = 8; 34 35 /** Constructor. 36 * @see org.greenstone.gatherer.util.Utility 37 */ 38 public NewCollectionDetailsPrompt() { 39 super(Gatherer.g_man); 40 this.cancelled = true; 41 this.self = this; 42 // Setup 43 setJMenuBar(new SimpleMenuBar("2.1")); 44 setModal(true); 45 setSize(size); 46 setTitle(get("Title")); 47 48 // Model building. Build a model of all of the collections in the gsdl collect directory with the appropriate directories and hardcode the big five. 49 Vector base_collection_model = new Vector(); 50 // Dummy item 51 File gsdl_collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)); 52 File[] possible_collections = gsdl_collection_directory.listFiles(); 53 for(int i = 0; possible_collections != null && i < possible_collections.length; i++) { 54 54 // The simpliest case is if the directory etc/collect.cfg file and a metadata/ in it. Thus it can easily be built upon. 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 55 File collect_cfg_file = new File(possible_collections[i], Utility.CONFIG_DIR); 56 File metadata_directory = new File(possible_collections[i], Utility.META_DIR); 57 if(collect_cfg_file.exists()) { 58 CollectionConfiguration collect_cfg = new CollectionConfiguration(collect_cfg_file); 59 String collection_name = collect_cfg.getName(); 60 // Even if there is no metadata directory we add it if its one of the 'big five + 1' that we know how to handle. 61 if(metadata_directory.exists() || collection_name.equals(Utility.COLLECTION_DLS) || collection_name.equals(Utility.COLLECTION_DEMO)) { /** @todo - the other big five */ 62 // Add to model. 63 Item item = new Item(possible_collections[i], collection_name); 64 if(!base_collection_model.contains(item)) { 65 base_collection_model.add(item); 66 } 67 } 68 // Else not a collection we know how to retrieve the metadata set for. 69 } 70 70 // Else not a collection at all. Someones pulling a fast one. 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 71 } 72 // Sort the result. 73 Collections.sort(base_collection_model); 74 base_collection_model.add(0, new Item(null, get("NewCollection"))); 75 // Creation. 76 JPanel content_pane = (JPanel) getContentPane(); 77 content_pane.setOpaque(true); 78 JPanel upper_pane = new JPanel(); 79 upper_pane.setOpaque(false); 80 JLabel instructions_label = new JLabel(get("Instructions")); 81 instructions_label.setOpaque(false); 82 JPanel title_pane = new JPanel(); 83 title_pane.setOpaque(false); 84 JLabel title_label = new JLabel(get("Collection_Title")); 85 title_label.setOpaque(false); 86 title = new JTextField(); 87 JPanel name_pane = new JPanel(); 88 name_pane.setOpaque(false); 89 JLabel name_label = new JLabel(get("Collection_Name")); 90 name_label.setOpaque(false); 91 JPanel file_pane = new JPanel(); 92 file_pane.setOpaque(false); 93 file = new RestrictedTextField(new RestrictedTextDocument(FILENAME_SIZE), "", FILENAME_SIZE); 94 JLabel file_label = new JLabel(".col"); 95 file_label.setOpaque(false); 96 JPanel email_pane = new JPanel(); 97 email_pane.setOpaque(false); 98 JLabel email_label = new JLabel(get("Collection_Email")); 99 email_label.setOpaque(false); 100 JPanel host_pane = new JPanel(); 101 host_pane.setOpaque(false); 102 JPanel address_pane = new JPanel(); 103 address_pane.setOpaque(false); 104 address = new JTextField(); 105 JLabel at_label = new JLabel("@"); 106 host = new JTextField(); 107 JPanel center_pane = new JPanel(); 108 center_pane.setOpaque(false); 109 JPanel description_pane = new JPanel(); 110 description_pane.setOpaque(false); 111 JLabel description_label = new JLabel(get("Collection_Description")); 112 description_label.setOpaque(false); 113 description = new JTextArea(); 114 description.setRows(5); 115 116 JPanel bottom_pane = new JPanel(); 117 // Base Collection 118 JPanel base_collection_pane = new JPanel(); 119 JLabel base_collection_label = new JLabel(get("Base_Collection")); 120 base_collection = new JComboBox(base_collection_model); 121 JButton base_collection_browse = new JButton(get("General.Browse")); 122 123 JPanel button_pane = new JPanel(); 124 button_pane.setOpaque(false); 125 create_button = new JButton(get("General.OK")); 126 create_button.setMnemonic(KeyEvent.VK_O); 127 JButton cancel_button = new JButton(get("General.Cancel")); 128 cancel_button.setMnemonic(KeyEvent.VK_C); 129 ColorListener email_color_listener = new ColorListener(address, host); 130 // Connection 131 base_collection_browse.addActionListener(new BrowseListener()); 132 cancel_button.addActionListener(new CancelListener()); 133 create_button.addActionListener(new CreateListener()); 134 address.addKeyListener(email_color_listener); 135 description.addKeyListener(new ColorListener(description)); 136 description.addKeyListener(new DescriptionListener()); 137 file.addKeyListener(new ColorListener(file)); 138 host.addKeyListener(email_color_listener); 139 title.addKeyListener(new ColorListener(title)); 140 title.getDocument().addDocumentListener(new TitleListener()); 141 // Layout 142 title_label.setPreferredSize(label_size); 143 144 title_pane.setLayout(new BorderLayout()); 145 title_pane.add(title_label, BorderLayout.WEST); 146 title_pane.add(title, BorderLayout.CENTER); 147 148 file_pane.setLayout(new BorderLayout()); 149 file_pane.add(file, BorderLayout.WEST); 150 file_pane.add(file_label, BorderLayout.CENTER); 151 152 name_label.setPreferredSize(label_size); 153 154 name_pane.setLayout(new BorderLayout()); 155 name_pane.add(name_label, BorderLayout.WEST); 156 name_pane.add(file_pane, BorderLayout.CENTER); 157 158 email_label.setPreferredSize(label_size); 159 160 address_pane.setLayout(new BorderLayout()); 161 address_pane.add(address, BorderLayout.CENTER); 162 address_pane.add(at_label, BorderLayout.EAST); 163 164 host_pane.setLayout(new GridLayout(1,2)); 165 host_pane.add(address_pane); 166 host_pane.add(host); 167 168 email_pane.setLayout(new BorderLayout()); 169 email_pane.add(email_label, BorderLayout.WEST); 170 email_pane.add(host_pane, BorderLayout.CENTER); 171 172 upper_pane.setLayout(new GridLayout(4,1)); 173 upper_pane.add(instructions_label); 174 upper_pane.add(title_pane); 175 upper_pane.add(name_pane); 176 upper_pane.add(email_pane); 177 178 description_pane.setLayout(new BorderLayout()); 179 description_pane.add(description_label, BorderLayout.NORTH); 180 description_pane.add(new JScrollPane(description), BorderLayout.CENTER); 181 182 base_collection_pane.setLayout(new BorderLayout()); 183 base_collection_pane.add(base_collection_label, BorderLayout.NORTH); 184 base_collection_pane.add(base_collection, BorderLayout.CENTER); 185 //base_collection_pane.add(base_collection_browse, BorderLayout.EAST); 186 187 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0)); 188 center_pane.setLayout(new BorderLayout()); 189 center_pane.add(description_pane, BorderLayout.CENTER); 190 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 191 bottom_pane.setLayout(new BorderLayout()); 192 bottom_pane.add(base_collection_pane, BorderLayout.CENTER); 193 bottom_pane.add(button_pane, BorderLayout.SOUTH); 194 195 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 196 button_pane.setLayout(new GridLayout(1,2)); 197 button_pane.add(create_button); 198 button_pane.add(cancel_button); 199 200 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 201 content_pane.setLayout(new BorderLayout()); 202 content_pane.add(upper_pane, BorderLayout.NORTH); 203 content_pane.add(center_pane, BorderLayout.CENTER); 204 content_pane.add(bottom_pane, BorderLayout.SOUTH); 205 // Final dialog setup & positioning. 206 Dimension screen_size = Gatherer.config.screen_size; 207 setLocation((screen_size.width - size.width) / 2, (screen_size.height - size.height) / 2); 208 show(); 209 } 210 211 public boolean isCancelled() { 212 return cancelled; 213 } 214 215 public File getBase() { 216 return base_final; 217 } 218 219 public String getDescription() { 220 return description_final; 221 } 222 223 public String getEmail() { 224 return email_final; 225 } 226 227 public String getName() { 228 return name_final; 229 } 230 231 public String getTitle() { 232 return title_final; 233 } 234 235 /** Gets a phrase from the dictionary based on key. 236 * @param key A <strong>String</strong> which serves as the unique identifier of a phrase. 237 * @return The desired phrase as a <strong>String</strong> or at least a meaningful error message. 238 */ 239 private String get(String key) { 240 if(key.indexOf(".") == -1) { 241 key = "NewCollectionPrompt." + key; 242 } 243 return Gatherer.dictionary.get(key); 244 } 245 246 private class BrowseListener 247 implements ActionListener { 248 public void actionPerformed(ActionEvent event) { 249 File file; 250 if(Gatherer.config.gsdl_path != null) { 251 file = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)); 252 } 253 else { 254 file = new File(Utility.BASE_DIR); 255 } 256 256 // Show OpenCollectionPrompt. 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 257 OpenCollectionDialog chooser = new OpenCollectionDialog(file); 258 file = chooser.getSelectedFile(); 259 if(file != null) { 260 file = file.getParentFile(); 261 CollectionConfiguration collect_cfg = new CollectionConfiguration(new File(file, Utility.META_DIR)); 262 Item item = new Item(file, collect_cfg.getName()); 263 base_collection.addItem(item); 264 base_collection.setSelectedItem(item); 265 } 266 } 267 } 268 269 private class CancelListener 270 implements ActionListener { 271 public void actionPerformed(ActionEvent event) { 272 cancelled = true; 273 self.dispose(); 274 } 275 } 276 277 private class ColorListener 278 extends KeyAdapter { 279 private JTextComponent component1; 280 private JTextComponent component2; 281 public ColorListener(JTextComponent component) { 282 this.component1 = component; 283 this.component2 = null; 284 } 285 public ColorListener(JTextComponent component1, JTextComponent component2) { 286 this.component1 = component1; 287 this.component2 = component2; 288 } 289 public void keyPressed(KeyEvent event) { 290 component1.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 291 component1.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 292 if(component2 != null) { 293 component2.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 294 component2.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 295 } 296 } 297 } 298 299 private class CreateListener 300 implements ActionListener { 301 public void actionPerformed(ActionEvent event) { 302 302 // Validate. 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 303 title_final = title.getText(); 304 if(title_final.length() == 0) { 305 GPrompt err_msg = new GPrompt(self, get("Error"), get("Title_Error"), "error.gif", null); 306 err_msg.display(); 307 err_msg.destroy(); 308 err_msg = null; 309 title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false)); 310 title.setBackground(Gatherer.config.getColor("coloring.error_background", false)); 311 return; 312 } 313 name_final = file.getText(); 314 if(name_final.length() > 0) { 315 // Determine if this filename is already in use. 316 File collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)); 317 File children[] = collection_directory.listFiles(); 318 for(int i = 0; children != null && i < children.length; i++) { 319 if(children[i].getName().equals(name_final)) { 320 GPrompt err_msg = new GPrompt(self, get("Error"), get("Name_Error"), "error.gif", null); 321 err_msg.display(); 322 err_msg.destroy(); 323 err_msg = null; 324 file.setForeground(Gatherer.config.getColor("coloring.error_foreground", false)); 325 file.setBackground(Gatherer.config.getColor("coloring.error_background", false)); 326 return; 327 } 328 } 329 } 330 else { 331 GPrompt err_msg = new GPrompt(self, get("Error"), get("Name_Error"), "error.gif", null); 332 err_msg.display(); 333 err_msg.destroy(); 334 err_msg = null; 335 file.setForeground(Gatherer.config.getColor("coloring.error_foreground", false)); 336 file.setBackground(Gatherer.config.getColor("coloring.error_background", false)); 337 return; 338 } 339 email_final = address.getText() + "@" + host.getText(); 340 if(email_final.length() == 0 || email_final.startsWith("@") || email_final.endsWith("@")) { 341 GPrompt err_msg = new GPrompt(self, get("Error"), get("Email_Error"), "error.gif", null); 342 err_msg.display(); 343 err_msg.destroy(); 344 err_msg = null; 345 address.setForeground(Gatherer.config.getColor("coloring.error_foreground", false)); 346 address.setBackground(Gatherer.config.getColor("coloring.error_background", false)); 347 host.setForeground(Gatherer.config.getColor("coloring.error_foreground", false)); 348 host.setBackground(Gatherer.config.getColor("coloring.error_background", false)); 349 return; 350 } 351 description_final = description.getText(); 352 if(description_final.length() == 0) { 353 GPrompt err_msg = new GPrompt(self, get("Error"), get("Description_Error"), "error.gif", null); 354 err_msg.display(); 355 err_msg.destroy(); 356 err_msg = null; 357 description.setForeground(Gatherer.config.getColor("coloring.error_foreground", false)); 358 description.setBackground(Gatherer.config.getColor("coloring.error_background", false)); 359 return; 360 } 361 description_final = Utility.encodeGreenstone(description_final); 362 362 // If we got this far there are no errors. 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 363 Item item_final = (Item) base_collection.getSelectedItem(); 364 base_final = item_final.getFile(); 365 366 cancelled = false; 367 368 self.dispose(); 369 } 370 } 371 372 private class DescriptionListener 373 extends KeyAdapter { 374 public void keyPressed(KeyEvent event) { 375 if(event.getKeyCode() == KeyEvent.VK_TAB) { 376 event.consume(); 377 base_collection.grabFocus(); 378 } 379 } 380 } 381 382 private class Item 383 implements Comparable { 384 private File file; 385 private String name; 386 public Item(File file, String name) { 387 this.file = file; 388 this.name = name; 389 } 390 public int compareTo(Object other) { 391 return toString().toLowerCase().compareTo(other.toString().toLowerCase()); 392 } 393 public boolean equals(Object other) { 394 return compareTo(other) == 0; 395 } 396 public File getFile() { 397 return file; 398 } 399 public String toString() { 400 return name; 401 } 402 } 403 404 private class RestrictedTextField 405 extends JTextField { 406 public RestrictedTextField(RestrictedTextDocument document, String value, int cols) { 407 super(document, "", cols); 408 } 409 protected Document createDefaultModel() { 410 return new RestrictedTextDocument(11); 411 } 412 } 413 414 private class RestrictedTextDocument 415 extends PlainDocument { 416 private char block[]; 417 private int cols; 418 private int current; 419 public RestrictedTextDocument(int cols) { 420 super(); 421 this.cols = cols; 422 this.current = 0; 423 } 424 public void blockChar(char c) { 425 if(block == null) { 426 block = new char[1]; 427 block[0] = c; 428 } 429 else { 430 char temp[] = block; 431 block = new char[temp.length + 1]; 432 System.arraycopy(temp, 0, block, 0, temp.length); 433 block[temp.length] = c; 434 temp = null; 435 } 436 } 437 public void insertString(int offs, String str, AttributeSet a) 438 throws BadLocationException { 439 439 // Remove any blocked characters. 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 440 StringBuffer temp = new StringBuffer(str); 441 for(int i = 0; block != null && i < block.length; i++) { 442 for(int j = temp.length() - 1; j >= 0; j--) { 443 if(temp.charAt(j) == block[i]) { 444 temp.deleteCharAt(j); 445 } 446 } 447 } 448 str = temp.toString(); 449 if(cols == -1 || str.length() + current <= cols) { 450 super.insertString(offs, str, a); 451 current = current + str.length(); 452 } 453 } 454 public void remove(int offs, int len) 455 throws BadLocationException { 456 super.remove(offs, len); 457 current = current - len; 458 } 459 } 460 461 private class TitleListener 462 implements DocumentListener { 463 /** Gives notification that an attribute or set of attributes changed. */ 464 public void changedUpdate(DocumentEvent e) { 465 updateFilename(); 466 } 467 467 468 469 470 471 468 /** Gives notification that there was an insert into the document. */ 469 public void insertUpdate(DocumentEvent e) { 470 updateFilename(); 471 } 472 472 473 /** Gives notification that a portion of the document has been removed. */ 474 public void removeUpdate(DocumentEvent e) { 475 updateFilename(); 476 } 477 478 private void updateFilename() { 479 String current_name = file.getText(); 480 String current_title = title.getText(); 481 StringBuffer temp = new StringBuffer(""); 482 int i = 0; 483 while(i < current_title.length() && temp.length() < 8) { 484 if(current_title.charAt(i) != ' ') { 485 temp.append(Character.toLowerCase(current_title.charAt(i))); 486 } 487 i++; 488 } 489 String result = temp.toString(); 490 if(current_name.startsWith(result) || result.startsWith(current_name)) { 491 file.setText(result); 492 } 493 } 494 } 495 473 /** Gives notification that a portion of the document has been removed. */ 474 public void removeUpdate(DocumentEvent e) { 475 updateFilename(); 476 } 477 478 private void updateFilename() { 479 String current_name = file.getText(); 480 String current_title = title.getText(); 481 StringBuffer temp = new StringBuffer(""); 482 int i = 0; 483 while(i < current_title.length() && temp.length() < 8) { 484 if(current_title.charAt(i) != ' ') { 485 temp.append(Character.toLowerCase(current_title.charAt(i))); 486 } 487 i++; 488 } 489 String result = temp.toString(); 490 if(current_name.startsWith(result) || result.startsWith(current_name)) { 491 file.setText(result); 492 } 493 } 494 } 496 495 } -
trunk/gli/src/org/greenstone/gatherer/gui/NewCollectionMetadataPrompt.java
r4297 r4367 19 19 20 20 public class NewCollectionMetadataPrompt 21 21 extends JDialog { 22 22 23 24 25 26 27 23 private boolean cancelled = true; 24 private CheckList sets_list; 25 private JDialog self; 26 private JList elements_list; 27 static private Dimension size = new Dimension(700, 380); 28 28 29 30 31 32 33 34 35 29 public NewCollectionMetadataPrompt() { 30 super(Gatherer.g_man, true); 31 this.self = this; 32 setJMenuBar(new SimpleMenuBar("2.1")); 33 setModal(true); 34 setSize(size); 35 setTitle(get("Title")); 36 36 37 38 39 40 41 42 43 44 45 46 47 37 // And the remaining metadata sets. 38 ArrayList sets = new ArrayList(); 39 // Determine what collections are available. 40 File metadata_directory = new File(Utility.METADATA_DIR); 41 File[] possible_mdses = metadata_directory.listFiles(); 42 for(int i = 0; i < possible_mdses.length; i++) { 43 String name = possible_mdses[i].getName(); 44 if(name.endsWith(".mds")) { 45 sets.add(new MetadataSet(possible_mdses[i])); 46 } 47 } 48 48 49 50 49 // Creation 50 JPanel content_pane = (JPanel) getContentPane(); 51 51 52 52 JLabel instructions_label = new JLabel(get("Metadata_Instructions")); 53 53 54 54 JPanel center_pane = new JPanel(); 55 55 56 57 58 59 56 JPanel sets_list_pane = new JPanel(); 57 JLabel sets_list_label = new JLabel(get("Select_MDS")); 58 sets_list_label.setOpaque(false); 59 sets_list = new CheckList(sets); 60 60 61 62 63 64 65 66 67 61 JPanel elements_list_pane = new JPanel(); 62 JLabel elements_list_label = new JLabel(get("Metadata_Elements")); 63 elements_list = new JList(); 64 elements_list.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 65 elements_list.setForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 66 elements_list.setSelectionBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 67 elements_list.setSelectionForeground(Gatherer.config.getColor("coloring.collection_tree_foreground", false)); 68 68 69 70 71 72 73 74 75 76 77 78 79 69 JPanel button_pane = new JPanel(); 70 JButton ok_button = new JButton(get("General.OK")); 71 JButton cancel_button = new JButton(get("General.Cancel")); 72 // Connection 73 ok_button.addActionListener(new OKButtonListener()); 74 cancel_button.addActionListener(new CancelButtonListener()); 75 sets_list.addListSelectionListener(new MetadataListSelectionListener()); 76 // Display 77 sets_list_pane.setLayout(new BorderLayout()); 78 sets_list_pane.add(sets_list_label, BorderLayout.NORTH); 79 sets_list_pane.add(new JScrollPane(sets_list), BorderLayout.CENTER); 80 80 81 82 83 81 elements_list_pane.setLayout(new BorderLayout()); 82 elements_list_pane.add(elements_list_label, BorderLayout.NORTH); 83 elements_list_pane.add(new JScrollPane(elements_list), BorderLayout.CENTER); 84 84 85 86 87 88 85 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 86 center_pane.setLayout(new GridLayout(2,1,0,5)); 87 center_pane.add(sets_list_pane); 88 center_pane.add(elements_list_pane); 89 89 90 91 92 93 90 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 91 button_pane.setLayout(new GridLayout(1,2,5,0)); 92 button_pane.add(ok_button); 93 button_pane.add(cancel_button); 94 94 95 96 97 98 99 100 101 102 103 104 95 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 96 content_pane.setLayout(new BorderLayout()); 97 content_pane.add(instructions_label, BorderLayout.NORTH); 98 content_pane.add(center_pane, BorderLayout.CENTER); 99 content_pane.add(button_pane, BorderLayout.SOUTH); 100 // Show 101 Dimension screen_size = Gatherer.config.screen_size; 102 setLocation((screen_size.width - size.width) / 2, (screen_size.height - size.height) / 2); 103 show(); 104 } 105 105 106 107 108 106 public ArrayList getSets() { 107 return sets_list.getSelected(); 108 } 109 109 110 111 112 110 public boolean isCancelled() { 111 return cancelled; 112 } 113 113 114 115 116 117 118 119 120 114 private void determineMetadataElements(MetadataSet extracted_metadata) { 115 // Hardcoded... 116 extracted_metadata.addElement("Encoding"); 117 extracted_metadata.addElement("Language"); 118 extracted_metadata.addElement("Source"); 119 extracted_metadata.addElement("Title"); 120 } 121 121 122 123 124 125 126 127 128 129 130 131 122 /** Gets a phrase from the dictionary based on key. 123 * @param key A <strong>String</strong> which serves as the unique identifier of a phrase. 124 * @return The desired phrase as a <strong>String</strong> or at least a meaningful error message. 125 */ 126 private String get(String key) { 127 if(key.indexOf(".") == -1) { 128 key = "NewCollectionPrompt." + key; 129 } 130 return Gatherer.dictionary.get(key); 131 } 132 132 133 134 135 136 137 138 139 133 private class CancelButtonListener 134 implements ActionListener { 135 public void actionPerformed(ActionEvent event) { 136 cancelled = true; 137 self.dispose(); 138 } 139 } 140 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 141 public class MetadataListSelectionListener 142 implements ListSelectionListener { 143 public void valueChanged(ListSelectionEvent event) { 144 if(!sets_list.isSelectionEmpty()) { 145 // Retrieve the selected set. 146 Entry entry = (Entry) sets_list.getSelectedValue(); 147 MetadataSet set = (MetadataSet) entry.getObject(); 148 entry = null; 149 // Build a model from its elements. 150 NodeList elements = set.getElements(); 151 set = null; 152 Vector elements_model = new Vector(); 153 for(int i = 0; i < elements.getLength(); i++) { 154 elements_model.add(new ElementWrapper(elements.item(i))); 155 } 156 elements = null; 157 Collections.sort(elements_model); 158 elements_list.setListData(elements_model); 159 elements_model = null; 160 } 161 else { 162 elements_list.setListData(new String[0]); 163 } 164 } 165 } 166 166 167 168 169 167 public class OKButtonListener 168 implements ActionListener { 169 public void actionPerformed(ActionEvent event) { 170 170 // See if the user has selected no metadata sets, and if so confirm thats what they really want. 171 172 173 174 175 176 177 178 179 180 181 182 183 184 171 ArrayList selected_sets = sets_list.getSelected(); 172 cancelled = false; 173 if(selected_sets.size() == 0) { 174 WarningDialog dialog = new WarningDialog("warning.NoMetadataSetsSelected", true); 175 if(dialog.display() == JOptionPane.OK_OPTION) { 176 // Otherwise we are free to go 177 self.dispose(); 178 } 179 } 180 else { 181 self.dispose(); 182 } 183 } 184 } 185 185 } 186 187 -
trunk/gli/src/org/greenstone/gatherer/gui/NewFolderPrompt.java
r4293 r4367 11 11 12 12 public class NewFolderPrompt 13 14 15 16 17 18 19 20 21 22 23 24 25 13 extends JDialog 14 implements ActionListener { 15 private FileNode node; 16 private JButton cancel_button; 17 private JButton ok_button; 18 private JTextField name_field; 19 private String name; 20 static final private Dimension LABEL_SIZE = new Dimension(100,25); 21 static final private Dimension SIZE = new Dimension(300,100); 22 public NewFolderPrompt(FileNode node) { 23 super(Gatherer.g_man, Gatherer.dictionary.get("NewFolderPrompt.Title"), true); 24 this.node = node; 25 } 26 26 27 28 29 30 31 32 33 34 35 27 public void actionPerformed(ActionEvent event) { 28 if(event.getSource() == ok_button) { 29 name = name_field.getText(); 30 } 31 else if(event.getSource() == cancel_button) { 32 name = null; 33 } 34 dispose(); 35 } 36 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 37 public String display() { 38 setSize(SIZE); 39 JPanel content_pane = (JPanel) getContentPane(); 40 JPanel name_pane = new JPanel(); 41 JLabel name_label = new JLabel(Gatherer.dictionary.get("NewFolderPrompt.Folder_Name")); 42 name_label.setPreferredSize(LABEL_SIZE); 43 name_field = new JTextField(getAutomaticName()); 44 JPanel button_pane = new JPanel(); 45 ok_button = new JButton(Gatherer.dictionary.get("General.OK")); 46 cancel_button = new JButton(Gatherer.dictionary.get("General.Cancel")); 47 // Connection 48 cancel_button.addActionListener(this); 49 ok_button.addActionListener(this); 50 // Layout 51 name_pane.setLayout(new BorderLayout()); 52 name_pane.add(name_label, BorderLayout.WEST); 53 name_pane.add(name_field, BorderLayout.CENTER); 54 54 55 56 57 55 button_pane.setLayout(new GridLayout(1,2,0,5)); 56 button_pane.add(ok_button); 57 button_pane.add(cancel_button); 58 58 59 60 61 62 63 64 65 66 67 68 59 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 60 content_pane.setLayout(new BorderLayout()); 61 content_pane.add(name_pane, BorderLayout.CENTER); 62 content_pane.add(button_pane, BorderLayout.SOUTH); 63 // Display 64 Rectangle frame_bounds = Gatherer.g_man.getBounds(); 65 setLocation(frame_bounds.x + (frame_bounds.width - SIZE.width) / 2, frame_bounds.y + (frame_bounds.height - SIZE.height) / 2); 66 show(); 67 return name; 68 } 69 69 70 71 72 73 74 75 76 77 78 79 80 70 private String getAutomaticName() { 71 File file = node.getFile(); 72 String default_name = Gatherer.dictionary.get("NewFolderPrompt.Default_Folder_Name"); 73 File temp_file = new File(file, default_name); 74 int count = 1; 75 if(temp_file.exists()) { 76 temp_file = new File(file, default_name + " " + count); 77 count++; 78 } 79 return temp_file.getName(); 80 } 81 81 } -
trunk/gli/src/org/greenstone/gatherer/gui/NumberField.java
r4293 r4367 6 6 7 7 public class NumberField 8 8 extends JTextField { 9 9 10 11 12 10 public NumberField(String text) { 11 super(text); 12 } 13 13 14 15 16 14 protected Document createDefaultModel() { 15 return new NumberDocument(); 16 } 17 17 18 19 18 static class NumberDocument 19 extends PlainDocument { 20 20 21 22 21 public void insertString(int offs, String str, AttributeSet a) 22 throws BadLocationException { 23 23 24 25 26 27 28 29 30 31 32 33 34 35 36 24 if (str == null) { 25 return; 26 } 27 char[] raw = str.toCharArray(); 28 StringBuffer result = new StringBuffer(""); 29 for (int i = 0; i < raw.length; i++) { 30 if(Character.isDigit(raw[i])) { 31 result.append(raw[i]); 32 } 33 } 34 super.insertString(offs, result.toString(), a); 35 } 36 } 37 37 } -
trunk/gli/src/org/greenstone/gatherer/gui/OpenCollectionDialog.java
r4293 r4367 54 54 55 55 public class OpenCollectionDialog 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 56 extends JFileChooser { 57 static final private ImageIcon LOCKED_COLLECTION_ICON = Utility.getImage("lcolicn.gif"); 58 static final private ImageIcon NORMAL_COLLECTION_ICON = Utility.getImage("ncolicn.gif"); 59 /** The name of the mouse listener that initiates editing on a double click. */ 60 static final private String SINGLE_CLICK_LISTENER = "SingleClickListener"; 61 /** Constructor */ 62 public OpenCollectionDialog(File file) { 63 super(file); 64 System.err.println("Size = " + getSize()); 65 // Other initialization 66 setAcceptAllFileFilterUsed(false); 67 setDialogTitle(Gatherer.dictionary.get("OpenCollectionDialog.Title")); 68 setFileFilter(new GathererFilter()); 69 setFileSystemView(new GathererFileSystemView()); 70 setFileView(new GathererFileView()); 71 setSize(400,300); 72 // Stop the annoying renaming 73 disableRename(this); 74 // Description accessory 75 DescriptionPreview accessory = new DescriptionPreview(this); 76 setAccessory(accessory); 77 // Move accessory 78 JPanel accessory_pane = (JPanel) accessory.getParent(); 79 JPanel center_pane = (JPanel) accessory_pane.getParent(); 80 center_pane.add(accessory_pane, BorderLayout.SOUTH); 81 // Done. 82 } 83 84 public String getFileName() { 85 // Continually loop until the use chooses an appropriate file or cancels. 86 while(true) { 87 int return_val = showOpenDialog(null); 88 if(return_val == JFileChooser.APPROVE_OPTION) { 89 File file = getSelectedFile(); 90 if(file != null && file.getName().endsWith(".col")) { 91 return file.getAbsolutePath(); 92 } 93 } 94 else { 95 return null; 96 } 97 } 98 } 99 100 /** Neat method to disable file renaming in filechooser. 101 * Thanks to: vladi21 from www.experts-exchange.com 102 */ 103 static public void disableRename(Component c) { 104 if (c instanceof JList){ 105 EventListener[] listeners=c.getListeners(MouseListener.class); 106 for(int i=0; listeners != null && i < listeners.length; i++) { 107 if (listeners[i].toString().indexOf(SINGLE_CLICK_LISTENER) != -1) { 108 c.removeMouseListener((MouseListener)listeners[i]); 109 } 110 } 111 return; 112 } 113 if (c instanceof Container) { 114 Component[] children = null; 115 children = ((Container)c).getComponents(); 116 if (children != null) { 117 for(int i = 0; children != null && i < children.length; i++) { 118 disableRename(children[i]); 119 } 120 } 121 } 122 } 123 124 static public void main(String args[]) { 125 JFrame frame = new JFrame(); 126 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 127 frame.setSize(800,640); 128 OpenCollectionDialog chooser = new OpenCollectionDialog(new File("/research/jmt12/gsdl/collect/")); 129 // Show dialog 130 int result = chooser.showOpenDialog(frame); 131 } 132 133 /* The DescriptionPreview accessory is adapted from the ImagePreview.java (an example used by FileChooserDemo2.java). */ 134 private class DescriptionPreview 135 extends JPanel 136 implements PropertyChangeListener { 137 private File file = null; 138 private JTextArea text; 139 //private JEditorPane text; 140 public DescriptionPreview(JFileChooser fc) { 141 setName("Description Preview"); 142 setPreferredSize(new Dimension(100, 75)); // About three rows. 143 144 text = new JTextArea(Gatherer.dictionary.get("OpenCollectionDialog.No_Description")); 145 145 //text.setLineWrap(true); 146 146 //text.setWrapStyleWord(true); … … 148 148 //text.setText(Gatherer.dictionary.get("OpenCollectionDialog.No_Description")); 149 149 150 151 152 153 154 155 156 157 158 159 150 setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 151 setLayout(new BorderLayout()); 152 add(new JScrollPane(text), BorderLayout.CENTER); 153 154 fc.addPropertyChangeListener(this); 155 } 156 /** Whenever a new file or folder is selected we determine what description should be displayed. */ 157 public void propertyChange(PropertyChangeEvent e) { 158 boolean update = false; 159 String prop = e.getPropertyName(); 160 160 //If the directory changed, don't show an image. 161 162 163 161 if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) { 162 file = null; 163 update = true; 164 164 165 166 167 168 169 165 //If a file became selected, find out which one. 166 } else if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) { 167 file = (File) e.getNewValue(); 168 update = true; 169 } 170 170 //Update the description accordingly. 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 171 if (update) { 172 if(file == null) { 173 text.setText(Gatherer.dictionary.get("OpenCollectionDialog.No_Description")); 174 } 175 else { 176 // Build a wrapper around the collection configuration file. 177 File config_file = new File(file.getParentFile(), Utility.CONFIG_DIR); 178 if(config_file.exists()) { 179 CollectionConfiguration collect_cfg = new CollectionConfiguration(config_file); 180 text.setText(collect_cfg.getDescription()); 181 text.setCaretPosition(0); 182 } 183 } 184 } 185 } 186 } 187 188 /** ImageFilter.java is a 1.4 example used by FileChooserDemo2.java. */ 189 private class GathererFilter 190 extends FileFilter { 191 191 192 193 194 195 192 //Accept all directories and all gif, jpg, tiff, or png files. 193 public boolean accept(File f) { 194 return (f.isDirectory() || f.getName().toLowerCase().endsWith(".col")); 195 } 196 196 197 198 199 200 201 202 203 204 197 //The description of this filter 198 public String getDescription() { 199 return Gatherer.dictionary.get("OpenCollectionDialog.Collection"); 200 } 201 } 202 203 private class GathererFileSystemView 204 extends FileSystemView { 205 205 206 206 private FileSystemView default_system_view = FileSystemView.getFileSystemView(); 207 207 208 209 210 211 212 213 214 215 208 /** Creates a new folder with a default folder name. */ 209 public File createNewFolder(File containingDir) 210 throws IOException { 211 return default_system_view.createNewFolder(containingDir); 212 } 213 214 /** Gets the list of shown (i.e. */ 215 public File[] getFiles(File dir, boolean useFileHiding) { 216 216 // Retrieve the files usually returned by the platform specific file system view. 217 217 File[] files = default_system_view.getFiles(dir, useFileHiding); 218 218 // Determine if the current dir actually contains a valid greenstone collection. To do this we check for the presence of the file <dir>/etc/collect.cfg and a directory named import or gimport. 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 219 File collect_cfg_file = new File(dir, Utility.CONFIG_DIR); 220 File import_dir_file = new File(dir, Utility.OLD_IMPORT_DIR); 221 File gimport_dir_file = new File(dir, Utility.IMPORT_DIR); 222 if(collect_cfg_file.exists() && (gimport_dir_file.exists() || import_dir_file.exists())) { 223 // Create a new dummy collection file. 224 String name = dir.getName(); 225 File collection_file = new File(dir, name + ".col"); 226 // If this file doesn't already exist. 227 if(!collection_file.exists()) { 228 File[] temp = new File[files.length + 1]; 229 System.arraycopy(files, 0, temp, 0, files.length); 230 temp[files.length] = collection_file; 231 files = temp; 232 temp = null; 233 } 234 collection_file = null; 235 name = null; 236 } 237 gimport_dir_file = null; 238 import_dir_file = null; 239 collect_cfg_file = null; 240 return files; 241 } 242 } 243 244 /** A FileView which returns differing icons depending on whether a lock file is present within the collection folder. */ 245 private class GathererFileView 246 extends FileView { 247 public String getDescription(File file) { 248 String description = null; 249 if(file.getName().endsWith(".col")) { 250 if(!lockExists(file)) { 251 Gatherer.dictionary.get("OpenCollectionDialog.Normal_Collection"); 252 } 253 else { 254 Gatherer.dictionary.get("OpenCollectionDialog.Locked_Collection"); 255 } 256 } 257 return description; 258 } 259 public Icon getIcon(File file) { 260 Icon icon = null; 261 if(file.getName().endsWith(".col")) { 262 if(!lockExists(file)) { 263 icon = NORMAL_COLLECTION_ICON; 264 } 265 else { 266 icon = LOCKED_COLLECTION_ICON; 267 } 268 } 269 return icon; 270 } 271 /** Determine if a lock file exists. */ 272 private boolean lockExists(File file) { 273 File lock_file = new File(file.getParentFile(), CollectionManager.LOCK_FILE); 274 return lock_file.exists(); 275 } 276 } 277 277 } -
trunk/gli/src/org/greenstone/gatherer/gui/OptionsBox.java
r4293 r4367 47 47 */ 48 48 public class OptionsBox 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 49 extends JDialog 50 implements ActionListener, FocusListener { 51 52 private JButton cancel_button; 53 private JButton establish_connection; 54 private JButton ok_button; 55 56 private JCheckBox use_colours; 57 private JCheckBox use_proxy; 58 59 private JLabel proxy_host_label; 60 private JLabel proxy_port_label; 61 62 private JTabbedPane tab_pane; 63 64 private JTextField proxy_host; 65 private JTextField proxy_port; 66 67 private JPanel button_pane; 68 private JPanel connection_pane; 69 private JPanel content_pane; 70 private JPanel download_pane; 71 private JPanel general_pane; 72 private JPanel proxy_pane; 73 private JPanel proxy_host_pane; 74 private JPanel proxy_port_pane; 75 76 static final private Dimension SIZE = new Dimension(400,300); 77 78 public OptionsBox() { 79 super(Gatherer.g_man); 80 81 this.setModal(true); 82 this.setTitle(get("Title")); 83 this.setSize(SIZE); 84 85 content_pane = (JPanel) this.getContentPane(); 86 content_pane.setLayout(new BorderLayout()); 87 content_pane.setMinimumSize(this.getSize()); 88 content_pane.setSize(this.getSize()); 89 content_pane.setMaximumSize(this.getSize()); 90 91 tab_pane = new JTabbedPane(); 92 93 tab_pane.add(get("General"), buildGeneral()); 94 if(!Gatherer.config.get("workflow.mirror", true)) { 95 tab_pane.add(get("Connection"), buildConnection()); 96 tab_pane.add(get("Download"), buildDownload()); 97 } 98 99 button_pane = new JPanel(new GridLayout(1,2)); 100 button_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 101 102 cancel_button = new JButton(get("General.Cancel")); 103 cancel_button.addActionListener(this); 104 105 ok_button = new JButton(get("General.OK")); 106 ok_button.addActionListener(this); 107 108 // Add components. 109 content_pane.add(tab_pane, BorderLayout.CENTER); 110 button_pane.add(ok_button); 111 button_pane.add(cancel_button); 112 content_pane.add(button_pane, BorderLayout.SOUTH); 113 114 // Final dialog setup & positioning. 115 // Position the window. 116 Dimension screen_size = Gatherer.config.screen_size; 117 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 118 show(); 119 } 120 121 public void actionPerformed(ActionEvent event) { 122 Object esrc = event.getSource(); 123 // OK - Save all settings. 124 if(esrc == ok_button) { 125 125 // Update config 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 BorderFactory.createBevelBorder(BevelBorder.LOWERED),166 get("Proxy_Configuration")));167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 126 this.dispose(); 127 } 128 // Cancel - Ignore settings and close. 129 else if(esrc == cancel_button) { 130 this.dispose(); 131 } 132 else if(esrc == use_proxy) { 133 Gatherer.config.set("general.use_proxy", true, use_proxy.isSelected()); 134 proxy_host.setEnabled(use_proxy.isSelected()); 135 proxy_port.setEnabled(use_proxy.isSelected()); 136 establish_connection.setEnabled(use_proxy.isSelected()); 137 } 138 else if(esrc == establish_connection) { 139 if(use_proxy.isSelected()) { 140 Gatherer.config.setString("general.proxy_host", true, proxy_host.getText()); 141 Gatherer.config.setString("general.proxy_port", true, proxy_port.getText()); 142 Gatherer.self.setProxy(); 143 } 144 } 145 } 146 147 public JPanel buildGeneral() { 148 general_pane = new JPanel(new GridLayout(2,1)); 149 JPanel color_pane = new JPanel(); 150 use_colours = new JCheckBox(get("Use_Colours")); 151 // Connection 152 use_colours.addActionListener(this); 153 // Layout 154 color_pane.add(use_colours); 155 156 general_pane.add(color_pane); 157 return general_pane; 158 } 159 160 public JPanel buildConnection() { 161 connection_pane = new JPanel(new BorderLayout()); 162 163 proxy_pane = new JPanel(new GridLayout(4,1)); 164 proxy_pane.setBorder(BorderFactory.createTitledBorder( 165 BorderFactory.createBevelBorder(BevelBorder.LOWERED), 166 get("Proxy_Configuration"))); 167 168 use_proxy = new JCheckBox(get("Use_Proxy")); 169 use_proxy.addActionListener(this); 170 171 establish_connection = new JButton(get("Establish_Connection")); 172 establish_connection.addActionListener(this); 173 174 proxy_host_pane = new JPanel(new BorderLayout()); 175 proxy_host_label = new JLabel(get("Proxy_Host")); 176 177 proxy_port_pane = new JPanel(new BorderLayout()); 178 proxy_port_label = new JLabel(get("Proxy_Port")); 179 180 if(Gatherer.config.get("general.use_proxy", true)) { 181 use_proxy.setSelected(true); 182 183 proxy_host = new JTextField(Gatherer.config.getString("general.proxy_host", true)); 184 proxy_port = new JTextField(Gatherer.config.getString("general.proxy_port", true)); 185 } 186 else { 187 use_proxy.setSelected(false); 188 proxy_host = new JTextField(); 189 proxy_host.setEnabled(false); 190 proxy_port = new JTextField(); 191 proxy_port.setEnabled(false); 192 193 establish_connection.setEnabled(false); 194 } 195 196 proxy_host.setColumns(40); 197 198 proxy_host.addActionListener(this); 199 proxy_host.addFocusListener(this); 200 proxy_port.addActionListener(this); 201 proxy_port.addFocusListener(this); 202 203 // Add lowest layer components 204 proxy_host_pane.add(proxy_host_label, BorderLayout.WEST); 205 proxy_host_pane.add(proxy_host, BorderLayout.CENTER); 206 207 proxy_port_pane.add(proxy_port_label, BorderLayout.WEST); 208 proxy_port_pane.add(proxy_port, BorderLayout.CENTER); 209 210 // Add components 211 proxy_pane.add(use_proxy); 212 proxy_pane.add(proxy_host_pane); 213 proxy_pane.add(proxy_port_pane); 214 proxy_pane.add(establish_connection); 215 216 // Add to higher layer. 217 connection_pane.add(proxy_pane, BorderLayout.CENTER); 218 219 return connection_pane; 220 } 221 222 public JPanel buildDownload() { 223 download_pane = new JPanel(new BorderLayout()); 224 return download_pane; 225 } 226 227 public void destroy() { 228 cancel_button = null; 229 establish_connection = null; 230 ok_button = null; 231 use_colours = null; 232 use_proxy = null; 233 proxy_host_label = null; 234 proxy_port_label = null; 235 tab_pane = null; 236 proxy_host = null; 237 proxy_port = null; 238 button_pane = null; 239 connection_pane = null; 240 content_pane = null; 241 download_pane = null; 242 general_pane = null; 243 proxy_pane = null; 244 proxy_host_pane = null; 245 proxy_port_pane = null; 246 } 247 248 // We have to trap focus changes and change them into action events. 249 public void focusGained(FocusEvent e) { 250 } 251 251 252 253 254 252 public void focusLost(FocusEvent event) { 253 actionPerformed(new ActionEvent(event.getSource(), event.getID(), "")); 254 } 255 255 256 257 258 259 260 261 256 private String get(String key) { 257 if(key.indexOf(".") == -1) { 258 key = "Options." + key; 259 } 260 return Gatherer.dictionary.get(key); 261 } 262 262 } -
trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java
r4346 r4367 88 88 89 89 /** The default constructor creates the few session length options, but either retrieves the rest from the current collection, or creates a default set of options. */ 90 91 92 93 94 95 90 public OptionsPane(JTextArea log, BuildOptions build_options) { 91 this.log_display = log; 92 this.build_options = build_options; 93 this.log_change_listener = new LogChangeListener(); 94 //this.target_pane = target_pane; 95 } 96 96 97 97 /** creates a new log from the text in log. The new file is named … … 126 126 } 127 127 128 128 /** This method creates the panel with all the build only options on it. 129 129 * @return A <strong>JPanel</strong> which can be used to display all the build only options. 130 130 */ 131 132 133 134 135 136 137 138 131 public JPanel buildBuild() { 132 JPanel pane = new JPanel(); 133 pane.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 134 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 135 int build_argument_count = build_options.getBuildArgumentCount(); 136 pane.setLayout(new GridLayout(build_argument_count, 1, 0, 0)); 137 int total_height = PANE_SIZE.height; 138 for(int i = 0; i < build_argument_count; i++) { 139 139 // Retrieve the argument so we know how to format the control. 140 140 Argument argument = build_options.getBuildArgument(i); 141 141 // Now attempt to retrieve any existing value for this argument. 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 142 boolean enabled = build_options.getBuildValueEnabled(argument.getName()); 143 String value = build_options.getBuildValue(argument.getName()); 144 ArgumentControl argument_control = new ArgumentControl(BUILD, argument, enabled, value); 145 total_height = total_height - argument_control.getPreferredSize().height; 146 pane.add(argument_control); 147 } 148 if(total_height > 0) { 149 JPanel filler = new JPanel(); 150 filler.setPreferredSize(new Dimension(100, total_height)); 151 filler.setSize(filler.getPreferredSize()); 152 pane.add(filler); 153 } 154 return pane; 155 } 156 /** This method creates the panel with all the import only options on it. 157 157 * @return A <strong>JPanel</strong> which can be used to display all the import only options. 158 158 */ 159 160 161 162 163 164 165 166 159 public JPanel buildImport() { 160 JPanel pane = new JPanel(); 161 pane.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 162 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 163 int import_argument_count = build_options.getImportArgumentCount(); 164 pane.setLayout(new GridLayout(import_argument_count, 1, 0, 0)); 165 int total_height = PANE_SIZE.height; 166 for(int i = 0; i < import_argument_count; i++) { 167 167 // Retrieve the argument so we know how to format the control. 168 168 Argument argument = build_options.getImportArgument(i); 169 169 // Now attempt to retrieve any existing value for this argument. 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 170 boolean enabled = build_options.getImportValueEnabled(argument.getName()); 171 String value = build_options.getImportValue(argument.getName()); 172 ArgumentControl argument_control = new ArgumentControl(IMPORT, argument, enabled, value); 173 total_height = total_height - argument_control.getPreferredSize().height; 174 pane.add(argument_control); 175 } 176 if(total_height > 0) { 177 JPanel filler = new JPanel(); 178 filler.setPreferredSize(new Dimension(100, total_height)); 179 filler.setSize(filler.getPreferredSize()); 180 pane.add(filler); 181 } 182 return pane; 183 } 184 /** This method is used to build a panel based on the message log, which is nothing like any of the other panels. 185 185 * @return A <strong>JPanel</strong> containing a scrollable text area which represents the shell process message log. 186 186 */ 187 188 189 190 187 public JPanel buildLog() { 188 // we now save the log pane 189 if (log_pane == null) { 190 log_pane = new JPanel(new BorderLayout()); 191 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 192 // Build a list of the log files available, ordering by last modified. Log files are like build_log.date.txt 193 DefaultListModel contents = new DefaultListModel(); 194 File log_directory = new File(Gatherer.c_man.getCollectionLog()); 195 File children[] = log_directory.listFiles(); 196 for(int i = 0; children != null && i < children.length; i++) { 197 if(children[i].getName().startsWith("build_log")&&children[i].getName().endsWith(".txt") ) { 198 FileEntry entry = new FileEntry(children[i]); 199 // We are about to insert it. But where. 200 boolean found = false; 201 for(int j = 0; j < contents.size(); j++) { 202 FileEntry sibling = (FileEntry) contents.getElementAt(j); 203 int order = entry.compareTo(sibling); 204 if(order > 0) { 205 contents.insertElementAt(entry, j); 206 found = true; 207 break; 208 } 209 } 210 if(!found) { 211 contents.addElement(entry); 212 } 213 } 214 } 215 215 216 217 218 219 220 216 log_list = new JList(contents); 217 log_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 218 log_list.setLayoutOrientation(JList.VERTICAL); 219 log_list.setVisibleRowCount(3); 220 log_list.addListSelectionListener(new LogListListener()); 221 221 222 222 JScrollPane list_scroller = new JScrollPane(log_list); 223 223 224 225 226 227 228 229 224 // If log is not empty and we have something in displayed_log - make that element selected 225 if (log_display.getText().length()>0 && displayed_log != null) { 226 int index = contents.indexOf(displayed_log); 227 if (index != -1) { 228 log_list.setSelectedIndex(index); 229 } 230 230 231 232 233 234 235 236 237 238 239 240 241 242 243 231 } 232 log_pane.add(new JScrollPane(log_display), BorderLayout.CENTER); 233 JLabel log_history_label = new JLabel(get("LogHistory")); 234 JPanel log_history_pane = new JPanel(); 235 log_history_pane.setLayout(new BorderLayout()); 236 log_history_pane.add(log_history_label, BorderLayout.NORTH); 237 log_history_pane.add(list_scroller, BorderLayout.SOUTH); 238 log_pane.add(log_history_pane, BorderLayout.SOUTH); 239 } 240 return log_pane; 241 } 242 243 /** This method retrieves a phrase from the dictionary based apon the key. 244 244 * @param key A <strong>String</strong> used as a reference to the correct phrase. 245 245 * @return A phrase, matching the key, as a <strong>String</strong>. 246 246 */ 247 248 249 250 247 private String get(String key) { 248 return get(key, null); 249 } 250 /** This method retrieves a phrase from the dictionary based apon the key and arguments. 251 251 * @param key A <strong>String</strong> used as a reference to the correct phrase. 252 252 * @param args A <strong>String[]</strong> whose contents are often substituted into the phrase before it is returned. … … 255 255 * @see org.greenstone.gatherer.Gatherer 256 256 */ 257 258 259 260 261 262 263 257 private String get(String key, String args[]) { 258 if(key.indexOf(".") == -1) { 259 key = "OptionsPane." + key; 260 } 261 return Gatherer.dictionary.get(key, args); 262 } 263 /** Attempts to discover the latest document count. 264 264 * @return An <strong>int</strong> detailing the number of documents in this collection. 265 265 */ 266 267 268 269 270 271 272 273 274 266 public int getDocumentCount() { 267 if(Gatherer.c_man.ready()) { 268 int count = Gatherer.c_man.getCollection().getDocumentCount(); 269 if(count != 0) { 270 return count; 271 } 272 } 273 return 1; 274 } 275 275 276 276 /** Loads a new log into the log text - saves the currently showing one, … … 348 348 349 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 350 /** Given a panel containing ArgumentControls, update the values associated with them. */ 351 public void update(JPanel panel) { 352 if(panel == log_pane) { 353 return; 354 } 355 356 for(int i = 0; i < panel.getComponentCount(); i++) { 357 Component component = panel.getComponent(i); 358 if(component instanceof ArgumentControl) { 359 ((ArgumentControl)component).update(); 360 } 361 } 362 } 363 364 private class ArgumentControl 365 extends JPanel { 366 private Argument argument; 367 private int type; 368 private JComponent value_control; 369 private JCheckBox enabled; 370 public ArgumentControl(int type, Argument argument, boolean enable, String value) { 371 super(); 372 this.argument = argument; 373 this.type = type; 374 String tooltip = Utility.formatHTMLWidth("<html>" + argument.getDesc() + "</html>", 60); 375 375 // Because of the dynamic order of component creation/connection/layout, we can't really follow that pattern here. 376 377 378 379 376 setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 377 setBorder(BorderFactory.createEmptyBorder(2,0,2,0)); 378 setLayout(new BorderLayout()); 379 setPreferredSize(ROW_SIZE); 380 380 381 381 /* 382 JPanel inner_pane = new JPanel();383 inner_pane.setOpaque(false);382 JPanel inner_pane = new JPanel(); 383 inner_pane.setOpaque(false); 384 384 */ 385 385 386 386 // Try to determine what the value_controls value should be. 387 388 389 387 if(value == null) { 388 value = argument.getDefaultValue(); 389 } 390 390 // Create a correct value control based on the argument provided. 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 391 switch(argument.getType()) { 392 case Argument.ENUM: 393 JComboBox combobox = new JComboBox(); 394 combobox.setEnabled(enable); 395 combobox.setToolTipText(tooltip); 396 // Set enabled 397 if(enable) { 398 combobox.setBackground(Color.white); 399 } 400 else { 401 combobox.setBackground(Color.lightGray); 402 } 403 // Build an option model, wrapping each entry of the list table. 404 HashMap arg_list = argument.getList(); 405 Iterator it = arg_list.keySet().iterator(); 406 while(it.hasNext()) { 407 combobox.addItem((String) it.next()); 408 } 409 // Connect this up first, so that if a value is selected the tooltip updates accordingly. 410 combobox.addActionListener(new ToolTipUpdater(arg_list)); 411 if(value != null) { 412 // Set the selected string. However since they are all strings we had best iterate ourselves. 413 for(int i = 0; i < combobox.getItemCount(); i++) { 414 if(combobox.getItemAt(i).toString().equals(value)) { 415 combobox.setSelectedIndex(i); 416 } 417 } 418 } 419 // Layout 420 add(combobox, BorderLayout.CENTER); 421 // And remember 422 value_control = combobox; 423 break; 424 case Argument.FLAG: 425 // Only need the check box. 426 value_control = null; 427 break; 428 case Argument.INTEGER: 429 // Build a spinner 430 JSpinner spinner = new JSpinner(); 431 spinner.setEnabled(enable); 432 spinner.setPreferredSize(SPINNER_SIZE); 433 spinner.setToolTipText(tooltip); 434 // Set enabled 435 JComponent c = spinner.getEditor(); 436 if ( c instanceof JSpinner.DefaultEditor ) { 437 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c; 438 JFormattedTextField field = editor.getTextField(); 439 field.setEditable(enable); 440 if(enable) { 441 field.setBackground(Color.white); 442 } 443 else { 444 field.setBackground(Color.lightGray); 445 } 446 } 447 // If there was an original value, set it. 448 if(value != null) { 449 try { 450 spinner.setValue(new Integer(value)); 451 } 452 catch (Exception error) { 453 } 454 } 455 // Layout 456 add(new JLabel(), BorderLayout.CENTER); 457 add(spinner, BorderLayout.EAST); 458 // And remember it 459 value_control = spinner; 460 break; 461 case Argument.STRING: 462 // Use a standard text field 463 JTextField textfield = new JTextField(); 464 textfield.setEnabled(enable); 465 textfield.setToolTipText(tooltip); 466 // Set enabled 467 if(enable) { 468 textfield.setBackground(Color.white); 469 } 470 else { 471 textfield.setBackground(Color.lightGray); 472 } 473 // If there was an original value, set it. 474 if(value != null) { 475 textfield.setText(value); 476 } 477 // Layout 478 add(textfield, BorderLayout.CENTER); 479 // And remember it 480 value_control = textfield; 481 break; 482 } 483 483 484 484 // If the argument is required, then you don't get a choice of whether it is enabled. 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 485 if(argument.isRequired()) { 486 JLabel label = new JLabel(argument.getName()); 487 label.setOpaque(false); 488 label.setPreferredSize(LABEL_SIZE); 489 label.setToolTipText(tooltip); 490 add(label, BorderLayout.WEST); 491 } 492 else { 493 enabled = new JCheckBox(argument.getName(), enable); 494 enabled.setOpaque(false); 495 enabled.setPreferredSize(LABEL_SIZE); 496 enabled.setToolTipText(tooltip); 497 // Connect 498 enabled.addActionListener(new EnabledListener(value_control)); 499 // Layout 500 add(enabled, BorderLayout.WEST); 501 } 502 } 503 504 /** Update the values stored in the collection so as to rememebr the current state of this argument. */ 505 public void update() { 506 String name = argument.getName(); 507 boolean enable = true; 508 if(enabled != null) { 509 enable = enabled.isSelected(); 510 } 511 String value = null; 512 if(value_control == null) { 513 // Flag value, nothing to do. 514 } 515 else if(value_control instanceof JTextField) { 516 value = ((JTextField)value_control).getText(); 517 } 518 else if(value_control instanceof JSpinner) { 519 value = ((JSpinner)value_control).getValue().toString(); 520 } 521 else if(value_control instanceof JComboBox) { 522 value = (String) ((JComboBox)value_control).getSelectedItem(); 523 } 524 524 // If this argument was a flag, but is now disabled, remove from the build options altogether 525 526 527 528 529 530 531 532 525 if(!enable && value == null) { 526 if(type == BUILD) { 527 build_options.removeBuildValue(name); 528 } 529 else { 530 build_options.removeImportValue(name); 531 } 532 } 533 533 // Otherwise update the argument value 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 534 else { 535 if(type == BUILD) { 536 build_options.setBuildValue(name, enable, value); 537 } 538 else { 539 build_options.setImportValue(name, enable, value); 540 } 541 } 542 } 543 } 544 545 /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */ 546 private class EnabledListener 547 implements ActionListener { 548 /** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */ 549 private JComponent target = null; 550 /** Constructor. */ 551 public EnabledListener(JComponent target) { 552 this.target = target; 553 } 554 /** Any implementation of ActionListener must include this method so that we can be informed when an action has been performed on or registered check box, prompting us to change the state of the other controls as per the users request. 555 555 * @param event An <strong>ActionEvent</strong> containing information about the click. 556 556 */ 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 557 public void actionPerformed(ActionEvent event) { 558 JCheckBox source = (JCheckBox)event.getSource(); 559 if(target != null) { 560 if(source.isSelected()) { 561 target.setBackground(Color.white); 562 target.setEnabled(true); 563 } 564 else { 565 target.setBackground(Color.lightGray); 566 target.setEnabled(false); 567 } 568 // Special case of stupid JSpinners who don't let their backgrounds change properly. 569 if(target instanceof JSpinner) { 570 JSpinner spinner = (JSpinner) target; 571 JComponent c = spinner.getEditor(); 572 if ( c instanceof JSpinner.DefaultEditor ) { 573 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c; 574 JFormattedTextField field = editor.getTextField(); 575 field.setEditable(source.isSelected()); 576 if(source.isSelected()) { 577 field.setBackground(Color.white); 578 } 579 else { 580 field.setBackground(Color.lightGray); 581 } 582 } 583 } 584 } 585 } 586 } 587 587 588 588 /** holds a File which has a particular naming convention … … 708 708 } 709 709 710 /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */ 711 private class ToolTipUpdater 712 implements ActionListener { 713 private HashMap arg_list; 714 public ToolTipUpdater(HashMap arg_list) { 715 this.arg_list = arg_list; 716 } 717 /** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly. 718 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call. 719 */ 720 public void actionPerformed(ActionEvent event) { 721 JComboBox source = (JComboBox)event.getSource(); 722 String key = (String) source.getSelectedItem(); 723 if(arg_list != null) { 724 String description = (String) arg_list.get(key); 725 if(description != null) { 726 description = Utility.formatHTMLWidth(DESCRIPTION_SEP + description, 60); 727 String original = source.getToolTipText(); 728 if(original == null) { 729 original = ""; 730 } 731 // Remove any existing extra description. 732 if(original.indexOf(DESCRIPTION_SEP) != -1) { 733 original = original.substring(0, original.indexOf(DESCRIPTION_SEP)); 734 } 735 source.setToolTipText(original + description); 736 } 737 } 738 } 739 } 740 741 710 /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */ 711 private class ToolTipUpdater 712 implements ActionListener { 713 private HashMap arg_list; 714 public ToolTipUpdater(HashMap arg_list) { 715 this.arg_list = arg_list; 716 } 717 /** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly. 718 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call. 719 */ 720 public void actionPerformed(ActionEvent event) { 721 JComboBox source = (JComboBox)event.getSource(); 722 String key = (String) source.getSelectedItem(); 723 if(arg_list != null) { 724 String description = (String) arg_list.get(key); 725 if(description != null) { 726 description = Utility.formatHTMLWidth(DESCRIPTION_SEP + description, 60); 727 String original = source.getToolTipText(); 728 if(original == null) { 729 original = ""; 730 } 731 // Remove any existing extra description. 732 if(original.indexOf(DESCRIPTION_SEP) != -1) { 733 original = original.substring(0, original.indexOf(DESCRIPTION_SEP)); 734 } 735 source.setToolTipText(original + description); 736 } 737 } 738 } 739 } 742 740 } -
trunk/gli/src/org/greenstone/gatherer/gui/Preferences.java
r4293 r4367 15 15 16 16 public class Preferences 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 17 extends JDialog { 18 19 private CheckList warning_preferences_check_list; 20 private JButton apply_button; 21 private JButton cancel_button; 22 private JButton ok_button; 23 private JCheckBox use_proxy_checkbox; 24 private JCheckBox workflow_browse; 25 private JCheckBox workflow_create; 26 private JCheckBox workflow_mirror; 27 private JCheckBox workflow_gather; 28 private JCheckBox workflow_enrich; 29 private JCheckBox workflow_design; 30 private JCheckBox workflow_export; 31 private JCheckBox workflow_preview; 32 private JTabbedPane tab_pane; 33 private JTextField proxy_host_field; 34 private JTextField proxy_port_field; 35 private Preferences self; 36 37 static final Dimension LABEL_SIZE = new Dimension(100, 25); 38 static final Dimension ROW_SIZE = new Dimension(380, 25); 39 static final Dimension SIZE = new Dimension(400, 320); 40 static final String TRUE = "true"; 41 42 public Preferences() { 43 // Initialize 44 super(Gatherer.g_man, true); 45 this.self = this; 46 setSize(SIZE); 47 setTitle("Preferences"); 48 // Creation 49 JPanel content_pane = (JPanel) getContentPane(); 50 tab_pane = new JTabbedPane(); 51 tab_pane.add("Preferences.Workflow", createWorkflowPreferences()); 52 tab_pane.add("Preferences.Connection", createConnectionPreferences()); 53 tab_pane.add("Preferences.Warnings", createWarningPreferences()); 54 55 JPanel button_pane = new JPanel(); 56 ok_button = new JButton("General.OK"); 57 apply_button = new JButton("General.Apply"); 58 cancel_button = new JButton("General.Cancel"); 59 // Connection 60 Gatherer.dictionary.register(this, null, false); 61 Gatherer.dictionary.register(tab_pane, null, false); 62 Gatherer.dictionary.register(ok_button, null, false); 63 Gatherer.dictionary.register(apply_button, null, false); 64 Gatherer.dictionary.register(cancel_button, null, false); 65 ok_button.addActionListener(new OKButtonListener(true)); 66 apply_button.addActionListener(new OKButtonListener(false)); 67 cancel_button.addActionListener(new CancelButtonListener()); 68 // Layout 69 button_pane.setBorder(BorderFactory.createEmptyBorder(5,2,2,2)); 70 button_pane.setLayout(new GridLayout(1,3,0,5)); 71 button_pane.add(ok_button); 72 button_pane.add(apply_button); 73 button_pane.add(cancel_button); 74 75 content_pane.setLayout(new BorderLayout()); 76 content_pane.add(tab_pane, BorderLayout.CENTER); 77 content_pane.add(button_pane, BorderLayout.SOUTH); 78 79 Dimension frame_size = Gatherer.g_man.getSize(); 80 Point frame_location = Gatherer.g_man.getLocation(); 81 //setLocation(frame_location.x + ((frame_size.width - SIZE.width) / 2), frame_location.y + ((frame_size.height - SIZE.height))); 82 setLocation(((frame_size.width - SIZE.width) / 2), ((frame_size.height - SIZE.height))); 83 84 // Clean up 85 frame_location = null; 86 frame_size = null; 87 cancel_button = null; 88 ok_button = null; 89 button_pane = null; 90 tab_pane = null; 91 content_pane = null; 92 show(); 93 } 94 95 private JPanel createConnectionPreferences() { 96 boolean currently_enabled = Gatherer.config.get("general.use_proxy", true); 97 // Creation 98 JPanel connection_pane = new JPanel(); 99 use_proxy_checkbox = new JCheckBox("Preferences.Connection.Use_Proxy", currently_enabled); 100 use_proxy_checkbox.setPreferredSize(ROW_SIZE); 101 JPanel proxy_host_pane = new JPanel(); 102 proxy_host_pane.setPreferredSize(ROW_SIZE); 103 JLabel proxy_host_label = new JLabel("Preferences.Connection.Proxy_Host"); 104 proxy_host_label.setPreferredSize(LABEL_SIZE); 105 proxy_host_field = new JTextField(Gatherer.config.getString("general.proxy_host", true)); 106 proxy_host_field.setEnabled(currently_enabled); 107 JPanel proxy_port_pane = new JPanel(); 108 proxy_port_pane.setPreferredSize(ROW_SIZE); 109 JLabel proxy_port_label = new JLabel("Preferences.Connection.Proxy_Port"); 110 proxy_port_label.setPreferredSize(LABEL_SIZE); 111 proxy_port_field = new NumberField(Gatherer.config.getString("general.proxy_port", true)); 112 proxy_port_field.setEnabled(currently_enabled); 113 114 // Connection 115 Gatherer.dictionary.register(use_proxy_checkbox, null, false); 116 Gatherer.dictionary.register(proxy_host_label, null, false); 117 Gatherer.dictionary.register(proxy_port_label, null, false); 118 use_proxy_checkbox.addActionListener(new UseProxyListener()); 119 // Layout 120 proxy_host_pane.setLayout(new BorderLayout()); 121 proxy_host_pane.add(proxy_host_label, BorderLayout.WEST); 122 proxy_host_pane.add(proxy_host_field, BorderLayout.CENTER); 123 124 proxy_port_pane.setLayout(new BorderLayout()); 125 proxy_port_pane.add(proxy_port_label, BorderLayout.WEST); 126 proxy_port_pane.add(proxy_port_field, BorderLayout.CENTER); 127 128 connection_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 129 connection_pane.add(use_proxy_checkbox); 130 connection_pane.add(proxy_host_pane); 131 connection_pane.add(proxy_port_pane); 132 133 return connection_pane; 134 } 135 136 /** The warning preferences are controlled through a checklist. */ 137 private JPanel createWarningPreferences() { 138 // Retrieve all of the warning preferences settings. 139 HashMap warning_preferences = Gatherer.config.getAll("warning\\..*", true); 140 warning_preferences_check_list = new CheckList(); 141 for(Iterator keys = warning_preferences.keySet().iterator(); keys.hasNext(); ) { 142 String property = (String) keys.next(); 143 String value = (String) warning_preferences.get(property); 144 144 // Remove 'warning.' 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 145 String title = Gatherer.dictionary.get(property.substring(8) + ".Title"); 146 Entry entry = new Entry(title, value.equalsIgnoreCase(TRUE)); 147 entry.setProperty(property); 148 warning_preferences_check_list.addEntry(entry); 149 } 150 // Creation 151 JPanel warning_preferences_pane = new JPanel(); 152 // Connection 153 // Layout 154 warning_preferences_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 155 warning_preferences_pane.setLayout(new BorderLayout()); 156 warning_preferences_pane.add(new JScrollPane(warning_preferences_check_list), BorderLayout.CENTER); 157 158 return warning_preferences_pane; 159 } 160 161 private JPanel createWorkflowPreferences() { 162 // Read in the predefined configurations file. 163 Vector predefined = new Vector(); 164 Document predefined_document = Utility.parse("xml/workflows.xml", true); 165 Element predefined_element = predefined_document.getDocumentElement(); 166 NodeList workflow_elements = predefined_element.getElementsByTagName("Workflow"); 167 for(int i = 0; i < workflow_elements.getLength(); i++) { 168 predefined.add(new WorkflowElementWrapper((Element)workflow_elements.item(i))); 169 } 170 // Creation 171 JPanel workflow_preferences_pane = new JPanel(); 172 JPanel checklist_pane = new JPanel(); 173 JLabel title_label = new JLabel("Preferences.Workflow.Title"); 174 title_label.setPreferredSize(ROW_SIZE); 175 XORToggleButtonGroup checkbox_group = new XORToggleButtonGroup(); 176 workflow_browse = new JCheckBox("Preferences.Workflow.Browse", Gatherer.config.get("workflow.browse", false)); 177 workflow_browse.setPreferredSize(ROW_SIZE); 178 workflow_mirror = new JCheckBox("Preferences.Workflow.Mirror", Gatherer.config.get("workflow.mirror", false)); 179 workflow_mirror.setPreferredSize(ROW_SIZE); 180 workflow_gather = new JCheckBox("Preferences.Workflow.Gather", Gatherer.config.get("workflow.gather", false)); 181 workflow_gather.setPreferredSize(ROW_SIZE); 182 workflow_enrich = new JCheckBox("Preferences.Workflow.Enrich", Gatherer.config.get("workflow.enrich", false)); 183 workflow_enrich.setPreferredSize(ROW_SIZE); 184 workflow_design = new JCheckBox("Preferences.Workflow.Design", Gatherer.config.get("workflow.design", false)); 185 workflow_design.setPreferredSize(ROW_SIZE); 186 workflow_export = new JCheckBox("Preferences.Workflow.Export", Gatherer.config.get("workflow.export", false)); 187 workflow_export.setPreferredSize(ROW_SIZE); 188 workflow_create = new JCheckBox("Preferences.Workflow.Create", Gatherer.config.get("workflow.create", false)); 189 workflow_create.setPreferredSize(ROW_SIZE); 190 workflow_preview = new JCheckBox("Preferences.Workflow.Preview", Gatherer.config.get("workflow.preview", false)); 191 workflow_preview.setPreferredSize(ROW_SIZE); 192 JPanel predefined_pane = new JPanel(); 193 JLabel predefined_label = new JLabel("Preferences.Workflow.Predefined.Label"); 194 predefined_label.setPreferredSize(new Dimension(150,25)); 195 JComboBox predefined_combobox = new JComboBox(predefined); 196 // Connection 197 checkbox_group.add(workflow_mirror); 198 checkbox_group.add(workflow_gather); 199 checkbox_group.add(workflow_enrich); 200 checkbox_group.add(workflow_design); 201 checkbox_group.add(workflow_export); 202 checkbox_group.add(workflow_create); 203 checkbox_group.add(workflow_preview); 204 Gatherer.dictionary.register(title_label, null, false); 205 Gatherer.dictionary.register(workflow_browse, null, false); 206 Gatherer.dictionary.register(workflow_mirror, null, false); 207 Gatherer.dictionary.register(workflow_gather, null, false); 208 Gatherer.dictionary.register(workflow_enrich, null, false); 209 Gatherer.dictionary.register(workflow_design, null, false); 210 Gatherer.dictionary.register(workflow_export, null, false); 211 Gatherer.dictionary.register(workflow_create, null, false); 212 Gatherer.dictionary.register(workflow_preview, null, false); 213 Gatherer.dictionary.register(predefined_label, null, false); 214 predefined_combobox.addActionListener(new PredefinedActionListener()); 215 // Layout 216 checklist_pane.setLayout(new BoxLayout(checklist_pane, BoxLayout.Y_AXIS)); 217 checklist_pane.add(title_label); 218 if(Gatherer.config.get("workflow.browse", true)) { 219 checklist_pane.add(workflow_browse); 220 } 221 if(Gatherer.config.get("workflow.mirror", true)) { 222 checklist_pane.add(workflow_mirror); 223 } 224 if(Gatherer.config.get("workflow.gather", true)) { 225 checklist_pane.add(workflow_gather); 226 } 227 if(Gatherer.config.get("workflow.enrich", true)) { 228 checklist_pane.add(workflow_enrich); 229 } 230 if(Gatherer.config.get("workflow.design", true)) { 231 checklist_pane.add(workflow_design); 232 } 233 if(Gatherer.config.get("workflow.export", true)) { 234 checklist_pane.add(workflow_export); 235 } 236 if(Gatherer.config.get("workflow.create", true)) { 237 checklist_pane.add(workflow_create); 238 } 239 if(Gatherer.config.get("workflow.preview", true)) { 240 checklist_pane.add(workflow_preview); 241 } 242 predefined_pane.setLayout(new BorderLayout()); 243 predefined_pane.add(predefined_label, BorderLayout.WEST); 244 predefined_pane.add(predefined_combobox, BorderLayout.CENTER); 245 246 workflow_preferences_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 247 workflow_preferences_pane.setLayout(new BorderLayout()); 248 workflow_preferences_pane.add(checklist_pane, BorderLayout.CENTER); 249 workflow_preferences_pane.add(predefined_pane, BorderLayout.SOUTH); 250 251 return workflow_preferences_pane; 252 } 253 254 public void dispose() { 255 // Deregister dictionary components 256 Gatherer.dictionary.deregister(this); 257 Gatherer.dictionary.deregister(tab_pane); 258 Gatherer.dictionary.deregister(ok_button); 259 Gatherer.dictionary.deregister(apply_button); 260 Gatherer.dictionary.deregister(cancel_button); 261 // Dispose 262 super.dispose(); 263 } 264 265 private class OKButtonListener 266 implements ActionListener { 267 private boolean close; 268 public OKButtonListener(boolean close) { 269 this.close = close; 270 } 271 public void actionPerformed(ActionEvent event) { 272 272 // Submit the various changes. 273 273 // Connection preferences 274 275 276 277 274 Gatherer.config.set("general.use_proxy", true, use_proxy_checkbox.isSelected()); 275 Gatherer.config.setString("general.proxy_host", true, proxy_host_field.getText()); 276 Gatherer.config.setString("general.proxy_port", true, proxy_port_field.getText()); 277 Gatherer.setProxy(); 278 278 // Warning preferences 279 280 281 282 279 for(int i = 0; i < warning_preferences_check_list.getEntryCount(); i++) { 280 Entry entry = warning_preferences_check_list.get(i); 281 Gatherer.config.set(entry.getProperty(), true, entry.isSelected()); 282 } 283 283 // Workflow preferences 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 284 Gatherer.config.set("workflow.browse", false, workflow_browse.isSelected()); 285 Gatherer.config.set("workflow.mirror", false, workflow_mirror.isSelected()); 286 Gatherer.config.set("workflow.gather", false, workflow_gather.isSelected()); 287 Gatherer.config.set("workflow.enrich", false, workflow_enrich.isSelected()); 288 Gatherer.config.set("workflow.design", false, workflow_design.isSelected()); 289 Gatherer.config.set("workflow.export", false, workflow_export.isSelected()); 290 Gatherer.config.set("workflow.create", false, workflow_create.isSelected()); 291 Gatherer.config.set("workflow.preview", false, workflow_preview.isSelected()); 292 Gatherer.g_man.workflowUpdate("Browser", workflow_browse.isSelected()); 293 Gatherer.g_man.workflowUpdate("Mirroring", workflow_mirror.isSelected()); 294 Gatherer.g_man.workflowUpdate("Collection", workflow_gather.isSelected()); 295 Gatherer.g_man.workflowUpdate("MetaEdit", workflow_enrich.isSelected()); 296 Gatherer.g_man.workflowUpdate("Build", workflow_design.isSelected()); 297 Gatherer.g_man.workflowUpdate("Export", workflow_export.isSelected()); 298 Gatherer.g_man.workflowUpdate("Create", workflow_create.isSelected()); 299 Gatherer.g_man.workflowUpdate("Preview", workflow_preview.isSelected()); 300 300 // Hide dialog 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 301 if(close) { 302 self.dispose(); 303 } 304 } 305 } 306 307 private class CancelButtonListener 308 implements ActionListener { 309 public void actionPerformed(ActionEvent event) { 310 self.dispose(); 311 } 312 } 313 314 private class PredefinedActionListener 315 implements ActionListener { 316 public void actionPerformed(ActionEvent event) { 317 JComboBox cb = (JComboBox) event.getSource(); 318 WorkflowElementWrapper element = (WorkflowElementWrapper) cb.getSelectedItem(); 319 CheckboxUpdater task = new CheckboxUpdater(element); 320 SwingUtilities.invokeLater(task); 321 } 322 323 private class CheckboxUpdater 324 implements Runnable { 325 private WorkflowElementWrapper element; 326 public CheckboxUpdater(WorkflowElementWrapper element) { 327 this.element = element; 328 } 329 public void run() { 330 workflow_browse.setSelected(element.getEnabled("browse")); 331 workflow_create.setSelected(element.getEnabled("create")); 332 workflow_mirror.setSelected(element.getEnabled("mirror")); 333 workflow_gather.setSelected(element.getEnabled("gather")); 334 workflow_enrich.setSelected(element.getEnabled("enrich")); 335 workflow_design.setSelected(element.getEnabled("design")); 336 workflow_export.setSelected(element.getEnabled("export")); 337 workflow_preview.setSelected(element.getEnabled("preview")); 338 } 339 } 340 } 341 342 private class UseProxyListener 343 implements ActionListener { 344 public void actionPerformed(ActionEvent event) { 345 boolean enabled = use_proxy_checkbox.isSelected(); 346 Gatherer.config.set("general.use_proxy", true, enabled); 347 347 // Fortunately this is already driven by the event thread. 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 348 proxy_host_field.setEnabled(enabled); 349 proxy_port_field.setEnabled(enabled); 350 } 351 } 352 353 private class WorkflowElementWrapper { 354 private Element element; 355 private String text; 356 public WorkflowElementWrapper(Element element) { 357 this.element = element; 358 } 359 public boolean getEnabled(String name) { 360 boolean result = true; 361 if(element.getAttribute(name).equalsIgnoreCase("false")) { 362 result = false; 363 } 364 return result; 365 } 366 public String toString() { 367 if(text == null) { 368 text = element.getFirstChild().getNodeValue(); 369 } 370 return text; 371 } 372 } 373 373 } 374 375 -
trunk/gli/src/org/greenstone/gatherer/gui/PreviewPane.java
r4356 r4367 46 46 47 47 public class PreviewPane 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 48 extends JPanel { 49 50 private CalHTMLPane view = null; 51 private int back_count = 0; 52 private int forward_count = 0; 53 private JButton back = null; 54 private JButton forward = null; 55 private JButton home = null; 56 private JButton reload = null; 57 private JLabel status = null; 58 private Observer observer = null; 59 private String args[] = null; 60 private String current_url = null; 61 private String page_showing = null; 62 private URL homepage = null; 63 64 public PreviewPane() { 65 // Create components 66 back = new JButton(get("Back"), Utility.getImage("back.gif")); 67 back.addActionListener(new BackListener()); 68 back.setEnabled(false); 69 70 home = new JButton(get("Home"), Utility.getImage("home.gif")); 71 home.addActionListener(new HomeListener()); 72 home.setEnabled(false); 73 74 forward = new JButton(get("Forward"), Utility.getImage("forward.gif")); 75 forward.addActionListener(new ForwardListener()); 76 forward.setEnabled(false); 77 78 reload = new JButton(get("Reload"), Utility.getImage("reload.gif")); 79 reload.addActionListener(new ReloadListener()); 80 reload.setEnabled(false); 81 82 CalHTMLPreferences prefs = new CalHTMLPreferences(); 83 observer = new Observer(); 84 view = new CalHTMLPane(prefs, observer, "Default"); 85 //view.setSize(new Dimension(770, 440)); 86 87 status = new JLabel(get("Ready")); 88 } 89 90 public void collectionChanged(boolean ready) { 91 } 92 93 public void display() { 94 JPanel control_pane = new JPanel(); 95 control_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); 96 control_pane.setLayout(new GridLayout(1,4)); 97 control_pane.add(back); 98 control_pane.add(reload); 99 control_pane.add(home); 100 control_pane.add(forward); 101 102 JPanel a_panel = new JPanel(new BorderLayout()); 103 a_panel.setSize(new Dimension(770, 440)); 104 a_panel.add(view, BorderLayout.CENTER); 105 106 setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); 107 setLayout(new BorderLayout()); 108 add(control_pane, BorderLayout.NORTH); 109 add(a_panel, BorderLayout.CENTER); 110 add(status, BorderLayout.SOUTH); 111 } 112 113 /** This method is called when the user selects the 'Preview' tab from the views bar. Can be used to display a particular page or perform some other relevant tests (ensure internet connection to specified server maybe?) 114 */ 115 public void gainFocus() { 116 if(Gatherer.c_man.ready() && Gatherer.c_man.built()) { 117 117 // Now load the collection 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 118 String url = Gatherer.config.exec_address.toString() + "?a=p&p=about&c=" + Gatherer.c_man.getCollection().getName(); 119 Gatherer.println("Loading " + url); 120 args = new String[1]; 121 args[0] = url; 122 status.setText(get("Loading", args)); 123 args = null; 124 view.showHTMLDocument((new GURL(url)).getURL()); 125 page_showing = url; 126 homepage = (new GURL(url)).getURL(); 127 url = null; 128 } 129 validate(); 130 } 131 132 /** Used to retrieve the phrase that matches the given key from the loaded dictionary. 133 */ 134 public String get(String key) { 135 return get(key, null); 136 } 137 138 public String get(String key, String args[]) { 139 if(key.indexOf(".") == -1) { 140 key = "Browser." + key; 141 } 142 return Gatherer.dictionary.get(key, args); 143 } 144 145 public void configServer(String command) { 146 try { 147 String url = Gatherer.config.exec_address.toString() + command; 148 System.err.println("Action: " + url); 149 view.setLoadSynchronously(true); 150 view.showHTMLDocument(new URL(url)); 151 view.setLoadSynchronously(false); 152 System.err.println("Complete."); 153 url = null; 154 } 155 catch(MalformedURLException error) { 156 System.err.println("Bad URL."); 157 } 158 } 159 160 public void validate() { 161 if(back_count > 0) { 162 back.setEnabled(true); 163 } 164 else { 165 back.setEnabled(false); 166 } 167 if(homepage != null) { 168 home.setEnabled(true); 169 } 170 else { 171 home.setEnabled(false); 172 } 173 if(forward_count > 0) { 174 forward.setEnabled(true); 175 } 176 else { 177 forward.setEnabled(false); 178 } 179 reload.setEnabled(true); 180 } 181 182 private class BackListener 183 implements ActionListener { 184 public void actionPerformed(ActionEvent event) { 185 view.goBack(); 186 back_count--; 187 forward_count++; 188 validate(); 189 } 190 } 191 192 private class ForwardListener 193 implements ActionListener { 194 public void actionPerformed(ActionEvent event) { 195 view.goForward(); 196 back_count++; 197 forward_count--; 198 validate(); 199 } 200 } 201 202 private class HomeListener 203 implements ActionListener { 204 public void actionPerformed(ActionEvent event) { 205 if(homepage != null) { 206 view.showHTMLDocument(homepage); 207 back_count++; 208 validate(); 209 } 210 } 211 } 212 213 private class ReloadListener 214 implements ActionListener { 215 public void actionPerformed(ActionEvent event) { 216 view.reloadDocument(); 217 } 218 } 219 220 private class Observer 221 extends DefaultCalHTMLObserver { 222 public int state = CalCons.DOC_LOADED; 223 public void linkActivatedUpdate(CalHTMLPane pane, URL url, String target_frame, String j_name) { 224 if(!url.toString().equals(current_url)) { 225 back_count++; 226 forward_count = 0; 227 validate(); 228 } 229 } 230 public void linkFocusUpdate(CalHTMLPane pane, URL url) { 231 231 ///ystem.err.println("Link in focus " + url.toString()); 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 232 args = new String[1]; 233 args[0] = url.toString(); 234 status.setText(get("Follow")); 235 args = null; 236 } 237 public void statusUpdate(CalHTMLPane pane, int state, URL url, int value, String message) { 238 this.state = state; 239 switch(state) { 240 // The Pane is attempting to connect to the given URL to receive data. 241 case CalCons.PRE_CONNECT: 242 ///ystem.err.println("Preconnect: " + state + " - " + message); 243 break; 244 // The Pane was unable to connect to the given URL or was unable to parse the content. Most likely this will be due to an incorrectly specified URL. The message argument may contain further details of the reason for failure. 245 case CalCons.PARSE_FAILED: 246 ///ystem.err.println("Parse Failed: " + state + " - " + message); 247 status.setText(get("CannotConnect") + message); 248 break; 249 // The Pane has established a connection to the given URL and is receiving any content. 250 case CalCons.CONNECTED: 251 ///ystem.err.println("Connected: " + state + " - " + message); 252 args = new String[1]; 253 args[0] = url.toString(); 254 status.setText(get("Loading", args)); 255 args = null; 256 break; 257 // The size of the content at the given URL is known and is contained in the value argument. 258 case CalCons.DOC_LENGTH: 259 ///ystem.err.println("Doc Length: " + state + " - " + message); 260 break; 261 // The title of the document for the given URL is known and is contained in the message argument. Only the title of a document in the Pane's top level frame will be sent to this method. If the document has no name, the message will be null, unless the document is a Frameset document in which case the message "Frameset" will be sent. 262 case CalCons.TITLE: 263 ///ystem.err.println("Title: " + state + " - " + message); 264 break; 265 // An exception has been thrown during parsing of the data from the URL. This will most likely be an IOException such as a server time-out. 266 case CalCons.PARSE_FAILED_POST_CONNECT: 267 ///ystem.err.println("Parse Failed Post Connect: " + state + " - " + message); 268 status.setText(get("TimedOut") + message); 269 break; 270 // The document has been parsed but formatting cannot be completed because the document contains images of unspecified size. The parsing thread is waiting for image updates to give it the information it needs to format and display the document. 271 case CalCons.WAITING_FOR_IMAGES: 272 ///ystem.err.println("Waiting For Images: " + state + " - " + message); 273 break; 274 // All text and image data has been received, parsed and the document structure determined. 275 case CalCons.DOC_LOADED: 276 ///ystem.err.println("Doc Loaded: " + state + " - " + message); 277 status.setText(get("Ready")); 278 break; 279 } 280 } 281 } 282 282 } -
trunk/gli/src/org/greenstone/gatherer/gui/SaveProgressDialog.java
r4293 r4367 64 64 65 65 public class SaveProgressDialog 66 66 extends Thread { 67 67 68 69 70 71 72 73 74 68 private Gatherer gatherer; 69 private JDialog dialog; 70 private JProgressBar progress; 71 static final public int METADATA = 50; 72 static final public int COLLECTION = 40; 73 static final public int MISC = 10; 74 static final private Dimension SIZE = new Dimension(300,30); 75 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 76 public SaveProgressDialog(Gatherer gatherer) { 77 this.gatherer = gatherer; 78 // Creation 79 dialog = new JDialog(); 80 dialog.setUndecorated(true); 81 dialog.setModal(true); 82 dialog.setSize(SIZE); 83 JPanel content_pane = (JPanel)dialog.getContentPane(); 84 progress = new JProgressBar(); 85 progress.setMinimum(0); 86 progress.setMaximum(100); 87 progress.setString(gatherer.get("SaveProgressDialog.Saving", "0")); 88 progress.setStringPainted(true); 89 // Layout 90 content_pane.setLayout(new BorderLayout()); 91 content_pane.add(progress, BorderLayout.CENTER); 92 Dimension screen_size = gatherer.config.screen_size; 93 dialog.setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 94 } 95 95 96 97 98 96 public void dispose() { 97 dialog.dispose(); 98 } 99 99 100 101 102 100 public void run() { 101 dialog.show(); // Modal. 102 } 103 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 104 public void update(final int amount) { 105 final JProgressBar final_progress = progress; 106 final Runnable update = new Runnable() { 107 public void run() { 108 progress.setValue(final_progress.getValue() + amount); 109 } 110 }; 111 try { 112 SwingUtilities.invokeLater(update); 113 } 114 catch (Exception e) { 115 gatherer.debug(e, "Error in SaveProgressDialog.update(): " + e); 116 } 117 } 118 118 } -
trunk/gli/src/org/greenstone/gatherer/gui/SimpleMenuBar.java
r4293 r4367 7 7 import org.greenstone.gatherer.util.Utility; 8 8 public class SimpleMenuBar 9 10 9 extends JMenuBar 10 implements ActionListener { 11 11 12 12 private String page_name; 13 13 14 15 16 17 14 public SimpleMenuBar(String page_name) { 15 this.page_name = page_name; 16 JMenu help = new JMenu(Gatherer.dictionary.get("Menu.Help")); 17 help.setIcon(Utility.HELP_ICON); 18 18 19 20 19 JMenuItem help_help = new JMenuItem(Gatherer.dictionary.get("Menu.Help")); 20 help_help.addActionListener(this); 21 21 22 22 help.add(help_help); 23 23 24 25 26 24 add(Box.createHorizontalGlue()); 25 add(help); 26 } 27 27 28 29 30 28 public void actionPerformed(ActionEvent event) { 29 Gatherer.g_man.help.setView(page_name); 30 } 31 31 } -
trunk/gli/src/org/greenstone/gatherer/gui/SmarterTable.java
r4293 r4367 53 53 /** An extension of a JTable that allows for the background, foreground, heading and selection colors to be set in single actions. */ 54 54 public class SmarterTable 55 55 extends JTable { 56 56 57 58 59 60 61 57 public void setBackground(Color color) { 58 super.setBackground(color); 59 TableCellRenderer renderer = getDefaultRenderer(String.class); 60 ((DefaultTableCellRenderer)renderer).setBackground(color); 61 } 62 62 63 64 65 66 67 63 public void setForeground(Color color) { 64 super.setForeground(color); 65 TableCellRenderer renderer = getDefaultRenderer(String.class); 66 ((DefaultTableCellRenderer)renderer).setForeground(color); 67 } 68 68 69 70 71 72 69 public void setHeadingBackground(Color color) { 70 JTableHeader header = getTableHeader(); 71 header.setBackground(color); 72 } 73 73 74 75 76 77 74 public void setHeadingForeground(Color color) { 75 JTableHeader header = getTableHeader(); 76 header.setForeground(color); 77 } 78 78 79 80 81 79 public void setSelectionColor(Color color) { 80 super.setSelectionBackground(color); 81 } 82 82 83 84 85 83 public void setSelectedTextColor(Color color) { 84 super.setSelectionForeground(color); 85 } 86 86 } -
trunk/gli/src/org/greenstone/gatherer/gui/SmarterTextArea.java
r4293 r4367 42 42 43 43 public class SmarterTextArea 44 44 extends JTextArea { 45 45 46 46 private boolean init = true; 47 47 48 49 50 48 public SmarterTextArea() { 49 super(); 50 } 51 51 52 53 54 55 56 57 58 59 52 public SmarterTextArea(String text, boolean editable) { 53 super(); 54 if(!editable) { 55 setDocument(new UnchangingDocument()); 56 } 57 setText(text); 58 init = false; 59 } 60 60 61 62 63 61 public int calculateColumnCount() { 62 return (getWidth() / getColumnWidth()); 63 } 64 64 65 66 67 68 69 70 71 72 73 74 75 65 private class UnchangingDocument 66 extends PlainDocument { 67 public void insertString(int offs, String str, AttributeSet a) 68 throws BadLocationException { 69 if(init) { 70 super.insertString(offs, str, a); 71 } 72 } 73 public void remove(int offs, int len) { 74 } 75 } 76 76 } -
trunk/gli/src/org/greenstone/gatherer/gui/SmarterTextField.java
r4293 r4367 46 46 47 47 public class SmarterTextField 48 49 50 51 48 extends JTextField { 49 public int calculateColumnCount() { 50 return (getWidth() / getColumnWidth()); 51 } 52 52 } -
trunk/gli/src/org/greenstone/gatherer/gui/SmarterTree.java
r4293 r4367 50 50 /** An extension of a JTree that allows for the background, foreground and selection colors to be set in single actions. */ 51 51 public class SmarterTree 52 52 extends JTree { 53 53 54 55 56 54 public SmarterTree() { 55 super(); 56 } 57 57 58 59 60 58 public SmarterTree(TreeModel model) { 59 super(model); 60 } 61 61 62 63 64 65 66 67 62 public void setBackground(Color color) { 63 super.setBackground(color); 64 if(cellRenderer != null) { 65 ((DefaultTreeCellRenderer)cellRenderer).setBackgroundNonSelectionColor(color); 66 } 67 } 68 68 69 70 71 72 73 74 69 public void setForeground(Color color) { 70 super.setForeground(color); 71 if(cellRenderer != null) { 72 ((DefaultTreeCellRenderer)cellRenderer).setTextNonSelectionColor(color); 73 } 74 } 75 75 76 77 78 76 public void setSelectionColor(Color color) { 77 ((DefaultTreeCellRenderer)cellRenderer).setBackgroundSelectionColor(color); 78 } 79 79 80 81 82 80 public void setSelectedTextColor(Color color) { 81 ((DefaultTreeCellRenderer)cellRenderer).setTextNonSelectionColor(color); 82 } 83 83 } -
trunk/gli/src/org/greenstone/gatherer/gui/SmudgyLabel.java
r4293 r4367 47 47 /** Just like a JLabel, except the text shown is updated using an overwriting runnable so that updates will only occur when process load is moderate. This functionality is currently disabled as it was somehow taking 5% of copy time, and not doing what it was supposed to anyway (the same event apparently can be added to the event queue over and over). */ 48 48 public class SmudgyLabel 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 49 extends JLabel { 50 private SmudgyUpdate update = null; 51 public SmudgyLabel(String text) { 52 super(text); 53 } 54 public void setText(String text) { 55 super.setText(text); 56 /* 57 if(update == null) { 58 update = new SmudgyUpdate(text); 59 } 60 else { 61 update.setText(text); 62 } 63 SwingUtilities.invokeLater(update); 64 */ 65 } 66 public void setTextImmediately(String text) { 67 super.setText(text); 68 } 69 private class SmudgyUpdate 70 implements Runnable { 71 private String text = null; 72 public SmudgyUpdate(String text) { 73 this.text = text; 74 } 75 public void run() { 76 setTextImmediately(text); 77 } 78 public void setText(String text) { 79 this.text = text; 80 } 81 } 82 82 83 83 } -
trunk/gli/src/org/greenstone/gatherer/gui/Splash.java
r4293 r4367 51 51 import org.greenstone.gatherer.util.Utility; 52 52 final public class Splash 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 53 extends JDialog { 54 private Dimension size = new Dimension(450,450); 55 public Splash() { 56 super(); 57 setSize(size); 58 setUndecorated(true); 59 JPanel content_pane = (JPanel) getContentPane(); 60 JLabel logo = new JLabel(Utility.getImage("gatherer.gif")); 61 content_pane.setBorder(BorderFactory.createRaisedBevelBorder()); 62 content_pane.setLayout(new BorderLayout()); 63 content_pane.add(logo, BorderLayout.CENTER); 64 // Center and display 65 Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize(); 66 setLocation((screen_size.width - size.width) / 2, (screen_size.height - size.height) / 2); 67 show(); 68 } 69 /** Destructor. */ 70 public void destroy() { 71 dispose(); 72 rootPane = null; 73 } 74 74 } -
trunk/gli/src/org/greenstone/gatherer/gui/TextFieldLabel.java
r4321 r4367 5 5 6 6 public class TextFieldLabel 7 8 9 10 11 12 13 14 15 16 17 18 7 extends JLabel { 8 static private JTextField FIELD = new JTextField("John"); 9 public TextFieldLabel(String text) { 10 this(text, true); 11 } 12 public TextFieldLabel(String text, boolean enabled) { 13 super(text); 14 FIELD.setEnabled(enabled); 15 setBackground(FIELD.getBackground()); 16 setBorder(FIELD.getBorder()); 17 setOpaque(true); 18 } 19 19 } -
trunk/gli/src/org/greenstone/gatherer/gui/WarningDialog.java
r4293 r4367 12 12 /** Warn a user that they are about to add folder level metadata. */ 13 13 public class WarningDialog 14 15 14 extends JDialog 15 implements ActionListener { 16 16 17 17 static final private Dimension SIZE = new Dimension(400,160); 18 18 19 20 21 22 23 24 19 private int result = JOptionPane.CANCEL_OPTION; 20 private JButton cancel_button; 21 private JButton ok_button; 22 private JCheckBox show_check; 23 private String full_property; 24 private String warning_name; 25 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 26 public WarningDialog(String full_property, boolean can_cancel) { 27 super(Gatherer.g_man, "Warning", true); 28 // Determine the name of this prompt. 29 this.full_property = full_property; 30 warning_name = full_property.substring(full_property.indexOf(".") + 1); 31 // Now build dialog. 32 setSize(SIZE); 33 setTitle(get("Title")); 34 // Creation 35 JPanel content_pane = (JPanel) getContentPane(); 36 JPanel text_pane = new JPanel(); 37 JLabel icon_label = new JLabel(Utility.getImage("gatherer_medium.gif")); 38 SmarterTextArea text_area = new SmarterTextArea(get("Message"), false); 39 text_area.setCaretPosition(0); 40 text_area.setLineWrap(true); 41 text_area.setWrapStyleWord(true); 42 JPanel bottom_pane = new JPanel(); 43 show_check = new JCheckBox(get("WarningDialog.Dont_Show_Again"), false); 44 JPanel control_pane = new JPanel(); 45 ok_button = new JButton(get("General.OK")); 46 cancel_button = new JButton(get("General.Cancel")); 47 // Connection 48 ok_button.addActionListener(this); 49 cancel_button.addActionListener(this); 50 // Layout 51 icon_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5)); 52 52 53 54 55 53 text_pane.setLayout(new BorderLayout()); 54 text_pane.add(icon_label, BorderLayout.WEST); 55 text_pane.add(new JScrollPane(text_area), BorderLayout.CENTER); 56 56 57 58 59 60 61 62 63 64 65 57 if(can_cancel) { 58 control_pane.setLayout(new GridLayout(1,2,5,0)); 59 control_pane.add(ok_button); 60 control_pane.add(cancel_button); 61 } 62 else { 63 control_pane.setLayout(new BorderLayout()); 64 control_pane.add(ok_button, BorderLayout.EAST); 65 } 66 66 67 68 69 70 67 bottom_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 68 bottom_pane.setLayout(new BorderLayout()); 69 bottom_pane.add(show_check, BorderLayout.CENTER); 70 bottom_pane.add(control_pane, BorderLayout.EAST); 71 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 72 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 73 content_pane.setLayout(new BorderLayout()); 74 content_pane.add(text_pane, BorderLayout.CENTER); 75 content_pane.add(bottom_pane, BorderLayout.SOUTH); 76 // Position 77 if(Gatherer.g_man != null) { 78 Rectangle frame_bounds = Gatherer.g_man.getBounds(); 79 setLocation(frame_bounds.x + (frame_bounds.width - SIZE.width) / 2, frame_bounds.y + (frame_bounds.height - SIZE.height) / 2); 80 } 81 else { 82 Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize(); 83 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 84 } 85 } 86 86 87 88 89 90 91 92 93 94 95 87 public void actionPerformed(ActionEvent event) { 88 if(event.getSource() == ok_button) { 89 result = JOptionPane.OK_OPTION; 90 } 91 // Store the state of the show message checkbox. 92 Gatherer.config.set(full_property, true, !show_check.isSelected()); 93 // Done. 94 dispose(); 95 } 96 96 97 98 99 97 public int display() { 98 ///ystem.err.println("Show " + full_property + ": " + Gatherer.config.get(full_property, false)); 99 if(Gatherer.config.get(full_property, false)) { 100 100 // We only show if the warning has not been disabled. 101 102 103 104 105 106 107 108 101 show(); 102 } 103 // We are no longer showing this dialog, so result must always be true. 104 else { 105 result = JOptionPane.OK_OPTION; 106 } 107 return result; 108 } 109 109 110 111 112 113 114 115 110 private String get(String key) { 111 if(key.indexOf(".") == -1) { 112 key = warning_name + "." + key; 113 } 114 return Gatherer.dictionary.get(key); 115 } 116 116 } -
trunk/gli/src/org/greenstone/gatherer/gui/border/TitledBorder.java
r4293 r4367 5 5 6 6 public class TitledBorder 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 7 extends javax.swing.border.TitledBorder { 8 /** The parent component of this border, which is not available until the Border has been realized. */ 9 private Component parent; 10 /** Creates a TitledBorder instance with the specified border and an empty title. */ 11 public TitledBorder(Border border) { 12 super(border); 13 } 14 /** Creates a TitledBorder instance with the specified border and title. */ 15 public TitledBorder(Border border, String title) { 16 super(border, title); 17 } 18 /** Creates a TitledBorder instance with the specified border, title, title-justification, and title-position. */ 19 public TitledBorder(Border border, String title, int justification, int position) { 20 super(border, title, justification, position); 21 } 22 /** Creates a TitledBorder instance with the specified border, title, title-justification, title-position, and title-font. */ 23 public TitledBorder(Border border, String title, int justification, int position, Font font) { 24 super(border, title, justification, position); 25 } 26 /** Creates a TitledBorder instance with the specified border, title, title-justification, title-position, title-font, and title-color. */ 27 public TitledBorder(Border border, String title, int justification, int position, Font font, Color color) { 28 super(border, title, justification, position, font, color); 29 } 30 /** Creates a TitledBorder instance. */ 31 public TitledBorder(String title) { 32 super(title); 33 } 34 /** Gets the parent of this component. */ 35 public Component getParent() { 36 return parent; 37 } 38 /** Paints the border for the specified component with the specified position and size. */ 39 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 40 // We assume that this border belongs to whatever component we paint it on. 41 parent = c; 42 // Now we continue normal painting. 43 super.paintBorder(c, g, x, y, width, height); 44 } 45 45 } 46
Note:
See TracChangeset
for help on using the changeset viewer.