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

Last change on this file since 7224 was 7224, checked in by kjdon, 20 years ago

tidied up the getXXXDir methods in Utility. Utility.getCollectionDir (which returns the path to the collect directory) has been renamed to getCollectDir, and a new Utility.getCollectionDir is provided which returns the path to an individual collection's base dir

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