source: trunk/gli/src/org/greenstone/gatherer/gui/NewCollectionDetailsPrompt.java@ 6540

Last change on this file since 6540 was 6318, checked in by jmt12, 21 years ago

Changed JButtons for GLIButtons, which know whether they should paint their background depending on what platform they are run on, and finished keyboard shortcuts

  • Property svn:keywords set to Author Date Id Revision
File size: 22.4 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Project, NZDL, University of Waikato
9 *
10 * Copyright (C) 2003 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.gui;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.io.File;
32import java.util.*;
33import javax.swing.*;
34import javax.swing.event.*;
35import javax.swing.text.*;
36import org.greenstone.gatherer.Dictionary;
37import org.greenstone.gatherer.Gatherer;
38import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
39import org.greenstone.gatherer.gui.GLIButton;
40import org.greenstone.gatherer.gui.SimpleMenuBar;
41import org.greenstone.gatherer.gui.ModalDialog;
42import org.greenstone.gatherer.util.StaticStrings;
43import org.greenstone.gatherer.util.Utility;
44
45public class NewCollectionDetailsPrompt
46 extends ModalDialog {
47
48 static public boolean titleClashes(String title, File current_config_file) {
49 File collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
50 File children[] = collection_directory.listFiles();
51 for(int i = 0; children != null && i < children.length; i++) {
52 if(children[i].isDirectory()) {
53 File config_file = new File(children[i], Utility.CONFIG_DIR);
54 if(current_config_file == null || !config_file.equals(current_config_file)) {
55 BasicCollectionConfiguration other_collection = new BasicCollectionConfiguration(config_file);
56 if(other_collection.getName().equalsIgnoreCase(title)) {
57 return true;
58 }
59 other_collection = null;
60 }
61 config_file = null;
62 }
63 }
64 return false;
65 }
66
67 private boolean cancelled;
68 private File base_final;
69 private JButton create_button;
70 private JComboBox base_collection;
71 private JDialog self;
72 private JTextArea description;
73 /* Suppress email
74 private JTextField address;
75 private JTextField host;
76 */
77 private JTextField title;
78 //private RestrictedTextField file;
79 private String description_final;
80 // private String email_final; no more email
81 // private String name_final;
82 private String title_final;
83 static private Dimension label_size = new Dimension(230, 25);
84 /** The size of this new collection dialog box. */
85 static private Dimension size = new Dimension(600, 280);
86 static private int FILENAME_SIZE = 8;
87
88 /** Constructor.
89 * @see org.greenstone.gatherer.util.Utility
90 */
91 public NewCollectionDetailsPrompt() {
92 super(Gatherer.g_man, true);
93 this.cancelled = true;
94 this.self = this;
95 // Setup
96 setJMenuBar(new SimpleMenuBar("creatingacollection"));
97 setSize(size);
98 Dictionary.setText(this, "NewCollectionPrompt.Title");
99
100 // Model building. Build a model of all of the collections in the gsdl collect directory with the appropriate directories and hardcode the big five.
101 Vector base_collection_model = new Vector();
102 // Dummy item
103 File gsdl_collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
104 File[] possible_collections = gsdl_collection_directory.listFiles();
105 for(int i = 0; possible_collections != null && i < possible_collections.length; i++) {
106 // The simpliest case is if the directory etc/collect.cfg file and a metadata/ in it. Thus it can easily be built upon.
107 File collect_cfg_file = new File(possible_collections[i], Utility.CONFIG_DIR);
108 File metadata_directory = new File(possible_collections[i], Utility.META_DIR);
109 if(collect_cfg_file.exists()) {
110 BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
111 String collection_name = collect_cfg.getName();
112 // Even if there is no metadata directory we add it if its one of the 'big five + 1' that we know how to handle.
113 if(metadata_directory.exists() || collection_name.equals(Utility.COLLECTION_DLS) || collection_name.equals(Utility.COLLECTION_DEMO)) {
114 // Add to model.
115 Item item = new Item(possible_collections[i], collect_cfg);
116 if(!base_collection_model.contains(item)) {
117 base_collection_model.add(item);
118 }
119 }
120 collection_name = null;
121 collect_cfg = null;
122 // Else not a collection we know how to retrieve the metadata set for.
123 }
124 // Else not a collection at all. Someones pulling a fast one.
125 }
126
127 // Sort the result.
128 Collections.sort(base_collection_model);
129 base_collection_model.add(0, new Item(null, Dictionary.get("NewCollectionPrompt.NewCollection")));
130
131 // Creation
132 JPanel content_pane = (JPanel) getContentPane();
133 content_pane.setOpaque(true);
134 JPanel upper_pane = new JPanel();
135 JLabel instructions_label = new JLabel();
136 Dictionary.setText(instructions_label, "NewCollectionPrompt.Instructions");
137 JPanel title_pane = new JPanel();
138 JLabel title_label = new JLabel();
139 Dictionary.setText(title_label, "CDM.General.Collection_Name");
140 title = new JTextField();
141 Dictionary.setTooltip(title, "CDM.General.Collection_Name_Tooltip");
142 JPanel name_pane = new JPanel();
143 JLabel name_label = new JLabel();
144 Dictionary.setText(name_label, "NewCollectionPrompt.Collection_Name");
145 //JPanel file_pane = new JPanel();
146 //file = new RestrictedTextField(new RestrictedTextDocument(FILENAME_SIZE), "", FILENAME_SIZE);
147 //Dictionary.setTooltip(file, "NewCollectionPrompt.Collection_Name_Tooltip");
148 //JLabel file_label = new JLabel(".col");
149 /* Suppress Email
150 JPanel email_pane = new JPanel();
151 JLabel email_label = new JLabel();
152 Dictionary.setText(email_label, "NewCollectionPrompt.Collection_Email");
153 JPanel host_pane = new JPanel();
154 JPanel address_pane = new JPanel();
155 address = new JTextField();
156 Dictionary.setTooltip(address, "CDM.General.Email.Creator_Tooltip");
157 JLabel at_label = new JLabel("@");
158 host = new JTextField();
159 Dictionary.setTooltip(host, "CDM.General.Email.Creator_Tooltip");
160 */
161
162 JPanel center_pane = new JPanel();
163 JPanel description_pane = new JPanel();
164 JLabel description_label = new JLabel();
165 Dictionary.setText(description_label, "NewCollectionPrompt.Collection_Description");
166 description = new JTextArea();
167 description.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
168 description.setForeground(Gatherer.config.getColor("coloring.editable_foreground", false));
169 description.setRows(5);
170 Dictionary.setTooltip(description, "CDM.General.Collection_Extra_Tooltip");
171
172 JPanel bottom_pane = new JPanel();
173 // Base Collection
174 JPanel base_collection_pane = new JPanel();
175 JLabel base_collection_label = new JLabel();
176 Dictionary.setText(base_collection_label, "NewCollectionPrompt.Base_Collection");
177 base_collection = new JComboBox(base_collection_model);
178 Dictionary.setTooltip(base_collection, "NewCollectionPrompt.Base_Collection_Tooltip");
179
180 JPanel button_pane = new JPanel();
181 create_button = new GLIButton();
182 create_button.setMnemonic(KeyEvent.VK_O);
183 Dictionary.setBoth(create_button, "General.OK", "General.OK_Tooltip");
184 JButton cancel_button = new GLIButton();
185 cancel_button.setMnemonic(KeyEvent.VK_C);
186 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
187
188 //ColorListener email_color_listener = new ColorListener(address, host); No more email
189
190 // Connection
191 cancel_button.addActionListener(new CancelListener());
192 create_button.addActionListener(new CreateListener());
193 //address.addKeyListener(email_color_listener); suppress email
194 description.addKeyListener(new ColorListener(description));
195 description.addKeyListener(new DescriptionListener());
196 //file.addKeyListener(new ColorListener(file));
197 //host.addKeyListener(email_color_listener); suppress email
198 title.addKeyListener(new ColorListener(title));
199 //title.getDocument().addDocumentListener(new TitleListener());
200 // Layout
201 title_label.setPreferredSize(label_size);
202
203 title_pane.setLayout(new BorderLayout());
204 title_pane.add(title_label, BorderLayout.WEST);
205 title_pane.add(title, BorderLayout.CENTER);
206
207 /* suppress filename
208 file_pane.setLayout(new BorderLayout());
209 file_pane.add(file, BorderLayout.WEST);
210 file_pane.add(file_label, BorderLayout.CENTER);
211
212 name_label.setPreferredSize(label_size);
213
214 name_pane.setLayout(new BorderLayout());
215 name_pane.add(name_label, BorderLayout.WEST);
216 name_pane.add(file_pane, BorderLayout.CENTER);
217 */
218
219 /* suppress email
220 email_label.setPreferredSize(label_size);
221
222 address_pane.setLayout(new BorderLayout());
223 address_pane.add(address, BorderLayout.CENTER);
224 address_pane.add(at_label, BorderLayout.EAST);
225
226 host_pane.setLayout(new GridLayout(1,2));
227 host_pane.add(address_pane);
228 host_pane.add(host);
229
230 email_pane.setLayout(new BorderLayout());
231 email_pane.add(email_label, BorderLayout.WEST);
232 email_pane.add(host_pane, BorderLayout.CENTER);
233 */
234
235 upper_pane.setLayout(new GridLayout(2,1));
236 upper_pane.add(instructions_label);
237 upper_pane.add(title_pane);
238 //upper_pane.add(name_pane);
239 //upper_pane.add(email_pane); no email anymore
240
241 description_pane.setLayout(new BorderLayout());
242 description_pane.add(description_label, BorderLayout.NORTH);
243 description_pane.add(new JScrollPane(description), BorderLayout.CENTER);
244
245 base_collection_label.setPreferredSize(label_size);
246
247 base_collection_pane.setLayout(new BorderLayout());
248 base_collection_pane.add(base_collection_label, BorderLayout.WEST);
249 base_collection_pane.add(base_collection, BorderLayout.CENTER);
250 // base_collection_pane.add(base_collection_browse, BorderLayout.EAST);
251
252 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
253 center_pane.setLayout(new BorderLayout());
254 center_pane.add(description_pane, BorderLayout.CENTER);
255
256 bottom_pane.setLayout(new BorderLayout());
257 bottom_pane.add(base_collection_pane, BorderLayout.CENTER);
258 bottom_pane.add(button_pane, BorderLayout.SOUTH);
259
260 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
261 button_pane.setLayout(new GridLayout(1,2));
262 button_pane.add(create_button);
263 button_pane.add(cancel_button);
264
265 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
266 content_pane.setLayout(new BorderLayout());
267 content_pane.add(upper_pane, BorderLayout.NORTH);
268 content_pane.add(center_pane, BorderLayout.CENTER);
269 content_pane.add(bottom_pane, BorderLayout.SOUTH);
270 // Final dialog setup & positioning.
271 Dimension screen_size = Gatherer.config.screen_size;
272 setLocation((screen_size.width - size.width) / 2, (screen_size.height - size.height) / 2);
273 setVisible(true);
274 }
275
276 public boolean isCancelled() {
277 return cancelled;
278 }
279
280 public File getBase() {
281 return base_final;
282 }
283
284 public String getDescription() {
285 return description_final;
286 }
287
288 /* No more email
289 public String getEmail() {
290 return email_final;
291 }
292 */
293
294 /** Generates the collection short filename by taking the first eight characters of the title (spaces removed) and then adjusting by further truncating and then adding an unique suffix as necessary.
295 * @return the filename as a String
296 */
297 public String getName() {
298 // Retrieve the first 8 non-whitespace characters of title_final.
299 StringBuffer name_buffer = new StringBuffer("");
300 int i = 0;
301 while(i < title_final.length() && name_buffer.length() < 8) {
302 char c = title_final.charAt(i);
303 // Arg. We need a few more tests than just whitespace
304 if(Character.isLetterOrDigit(c)) {
305 name_buffer.append(Character.toLowerCase(c));
306 }
307 i++;
308 }
309 // We need to ensure the filename is unique
310 int counter = 0;
311 StringBuffer new_name_buffer = new StringBuffer(name_buffer.toString());
312 while(filenameClashes(new_name_buffer.toString())) {
313 new_name_buffer = new StringBuffer(name_buffer.toString());
314 counter++;
315 String suffix = String.valueOf(counter);
316 // If we have to truncate the namestring so as to fit the suffix
317 if(suffix.length() + new_name_buffer.length() > 8) {
318 new_name_buffer.replace(new_name_buffer.length() - suffix.length(), new_name_buffer.length(), suffix);
319 }
320 // Or just append it if that isn't necessary
321 else {
322 new_name_buffer.append(suffix);
323 }
324
325 }
326 // All done
327 return new_name_buffer.toString();
328 }
329
330 private boolean filenameClashes(String filename) {
331 File collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
332 File children[] = collection_directory.listFiles();
333 for(int i = 0; children != null && i < children.length; i++) {
334 if(children[i].getName().equals(filename)) {
335 return true;
336 }
337 }
338 return false;
339 }
340
341 public String getTitle() {
342 return title_final;
343 }
344
345
346 private class BrowseListener
347 implements ActionListener {
348 public void actionPerformed(ActionEvent event) {
349 File file;
350 if(Gatherer.config.gsdl_path != null) {
351 file = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
352 }
353 else {
354 file = new File(Utility.BASE_DIR);
355 }
356 // Show OpenCollectionPrompt.
357 OpenCollectionDialog chooser = new OpenCollectionDialog(file);
358 file = chooser.getSelectedFile();
359 if(file != null) {
360 file = file.getParentFile();
361 BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(new File(file, Utility.META_DIR));
362 Item item = new Item(file, collect_cfg);
363 base_collection.addItem(item);
364 base_collection.setSelectedItem(item);
365 collect_cfg = null;
366 }
367 }
368 }
369
370 private class CancelListener
371 implements ActionListener {
372 public void actionPerformed(ActionEvent event) {
373 cancelled = true;
374 self.dispose();
375 }
376 }
377
378 private class ColorListener
379 extends KeyAdapter {
380 private JTextComponent component1;
381 private JTextComponent component2;
382 public ColorListener(JTextComponent component) {
383 this.component1 = component;
384 this.component2 = null;
385 }
386 public ColorListener(JTextComponent component1, JTextComponent component2) {
387 this.component1 = component1;
388 this.component2 = component2;
389 }
390 public void keyPressed(KeyEvent event) {
391 component1.setForeground(Gatherer.config.getColor("coloring.editable_foreground", false));
392 component1.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
393 if(component2 != null) {
394 component2.setForeground(Gatherer.config.getColor("coloring.editable_foreground", false));
395 component2.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
396 }
397 }
398 }
399
400 private class CreateListener
401 implements ActionListener {
402
403 public void actionPerformed(ActionEvent event) {
404 // Validate.
405 title_final = title.getText();
406 if(title_final.length() == 0) {
407 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
408 title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
409 title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
410 return;
411 }
412 // We must ensure that the collection title is unique. This is a pain in the nether regions as we are forced to load the collect.cfg of each other collection in turn looking for a conflicting title
413 else {
414 if(titleClashes(title_final, null)) {
415 if(JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Clash"), Dictionary.get("General.Warning"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.NO_OPTION) {
416 title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
417 title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
418 return;
419 }
420 }
421 }
422 /* Suppress filename
423 name_final = file.getText();
424 if(name_final.length() > 0) {
425 // Determine if this filename is already in use.
426 File collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
427 File children[] = collection_directory.listFiles();
428 for(int i = 0; children != null && i < children.length; i++) {
429 if(children[i].getName().equals(name_final)) {
430 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Name_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
431 file.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
432 file.setBackground(Gatherer.config.getColor("coloring.error_background", false));
433 return;
434 }
435 }
436 }
437 else {
438 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Name_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
439 file.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
440 file.setBackground(Gatherer.config.getColor("coloring.error_background", false));
441 return;
442 }
443 */
444 /* Suppress email
445 email_final = address.getText() + "@" + host.getText();
446 if(email_final.length() == 0 || email_final.startsWith("@") || email_final.endsWith("@")) {
447 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Email_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
448 address.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
449 address.setBackground(Gatherer.config.getColor("coloring.error_background", false));
450 host.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
451 host.setBackground(Gatherer.config.getColor("coloring.error_background", false));
452 return;
453 }
454 */
455 description_final = description.getText();
456 if(description_final.length() == 0) {
457 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Description_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
458 description.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
459 description.setBackground(Gatherer.config.getColor("coloring.error_background", false));
460 return;
461 }
462 // If we got this far there are no errors.
463 Item item_final = (Item) base_collection.getSelectedItem();
464 base_final = item_final.getFile();
465
466 cancelled = false;
467
468 self.dispose();
469 }
470 }
471
472 private class DescriptionListener
473 extends KeyAdapter {
474 public void keyPressed(KeyEvent event) {
475 if(event.getKeyCode() == KeyEvent.VK_TAB) {
476 event.consume();
477 base_collection.grabFocus();
478 }
479 }
480 }
481
482 private class Item
483 implements Comparable {
484 private BasicCollectionConfiguration config;
485 private File file;
486 private String name;
487 public Item(File file, BasicCollectionConfiguration config) {
488 this.config = config;
489 this.file = file;
490 this.name = null;
491 }
492 public Item(File file, String name) {
493 this.config = null;
494 this.file = file;
495 this.name = name;
496 }
497 public int compareTo(Object other) {
498 return toString().toLowerCase().compareTo(other.toString().toLowerCase());
499 }
500 public boolean equals(Object other) {
501 return compareTo(other) == 0;
502 }
503 public File getFile() {
504 return file;
505 }
506 public String toString() {
507 if(name == null && config != null) {
508 StringBuffer title_buffer = new StringBuffer(config.getName());
509 title_buffer.append(StaticStrings.SPACE_CHARACTER);
510 title_buffer.append(StaticStrings.OPEN_PARENTHESIS_CHARACTER);
511 title_buffer.append(config.getShortName());
512 title_buffer.append(StaticStrings.CLOSE_PARENTHESIS_CHARACTER);
513 name = title_buffer.toString();
514 title_buffer = null;
515 }
516 return name;
517 }
518 }
519
520 /*
521 private class RestrictedTextField
522 extends JTextField {
523 public RestrictedTextField(RestrictedTextDocument document, String value, int cols) {
524 super(document, "", cols);
525 }
526 protected Document createDefaultModel() {
527 return new RestrictedTextDocument(11);
528 }
529 }
530
531 private class RestrictedTextDocument
532 extends PlainDocument {
533 private char block[];
534 private int cols;
535 private int current;
536 public RestrictedTextDocument(int cols) {
537 super();
538 this.cols = cols;
539 this.current = 0;
540 }
541 public void blockChar(char c) {
542 if(block == null) {
543 block = new char[1];
544 block[0] = c;
545 }
546 else {
547 char temp[] = block;
548 block = new char[temp.length + 1];
549 System.arraycopy(temp, 0, block, 0, temp.length);
550 block[temp.length] = c;
551 temp = null;
552 }
553 }
554 public void insertString(int offs, String str, AttributeSet a)
555 throws BadLocationException {
556 // Remove any blocked characters.
557 StringBuffer temp = new StringBuffer(str);
558 for(int i = 0; block != null && i < block.length; i++) {
559 for(int j = temp.length() - 1; j >= 0; j--) {
560 if(temp.charAt(j) == block[i]) {
561 temp.deleteCharAt(j);
562 }
563 }
564 }
565 str = temp.toString();
566 if(cols == -1 || str.length() + current <= cols) {
567 super.insertString(offs, str, a);
568 current = current + str.length();
569 }
570 }
571 public void remove(int offs, int len)
572 throws BadLocationException {
573 super.remove(offs, len);
574 current = current - len;
575 }
576 }
577 */
578
579 /* Suppress filename
580 private class TitleListener
581 implements DocumentListener {
582 ** Gives notification that an attribute or set of attributes changed. *
583 public void changedUpdate(DocumentEvent e) {
584 updateFilename();
585 }
586
587 ** Gives notification that there was an insert into the document. *
588 public void insertUpdate(DocumentEvent e) {
589 updateFilename();
590 }
591
592 ** Gives notification that a portion of the document has been removed. *
593 public void removeUpdate(DocumentEvent e) {
594 updateFilename();
595 }
596
597 private void updateFilename() {
598 String current_name = file.getText();
599 String current_title = title.getText();
600 StringBuffer temp = new StringBuffer("");
601 int i = 0;
602 while(i < current_title.length() && temp.length() < 8) {
603 if(current_title.charAt(i) != ' ') {
604 temp.append(Character.toLowerCase(current_title.charAt(i)));
605 }
606 i++;
607 }
608 String result = temp.toString();
609 if(current_name.startsWith(result) || result.startsWith(current_name)) {
610 file.setText(result);
611 }
612 }
613 }
614 */
615}
616
617
618
Note: See TracBrowser for help on using the repository browser.