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

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

in gs3 can now base a coll on one in another site

  • Property svn:keywords set to Author Date Id Revision
File size: 15.5 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. It 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;
54 if (Gatherer.GS3) {
55 collection_directory = new File(Utility.getCollectDir(Gatherer.config.gsdl3_path, Gatherer.config.site_name));
56 } else {
57 collection_directory = new File(Utility.getCollectDir(Gatherer.config.gsdl_path));
58 }
59 File children[] = collection_directory.listFiles();
60 for(int i = 0; children != null && i < children.length; i++) {
61 if(children[i].isDirectory()) {
62 File config_file = new File(children[i], Utility.CONFIG_FILE);
63 if(current_config_file == null || !config_file.equals(current_config_file)) {
64 BasicCollectionConfiguration other_collection = new BasicCollectionConfiguration(config_file);
65 if(other_collection.getName().equalsIgnoreCase(title)) {
66 return true;
67 }
68 other_collection = null;
69 }
70 config_file = null;
71 }
72 }
73 return false;
74 }
75
76 private boolean cancelled;
77 private File base_final;
78 private JButton create_button;
79 private JComboBox base_collection;
80 private JDialog self;
81 private JTextArea description;
82 private JTextField title;
83 private String description_final;
84 private String title_final;
85 static private Dimension COMPONENT_SIZE = new Dimension(230, 25);
86 /** The size of this new collection dialog box. */
87 static private Dimension SIZE = new Dimension(600, 280);
88 static private int FILENAME_SIZE = 8;
89
90 /** Constructor.
91 * @see org.greenstone.gatherer.util.Utility
92 */
93 public NewCollectionDetailsPrompt() {
94 super(Gatherer.g_man, true);
95 this.cancelled = true;
96 this.self = this;
97 // Setup
98 setJMenuBar(new SimpleMenuBar("creatingacollection"));
99 setSize(SIZE);
100 Dictionary.setText(this, "NewCollectionPrompt.Title");
101
102 // Model building. Build a model of all of the collections in the gsdl collect directory with the appropriate directories.
103 Vector base_collection_model = new Vector();
104 // need to modify this to base a coll on any collection from any site
105 if (Gatherer.GS3) {
106 File sites_dir = new File(Utility.getSitesDir(Gatherer.config.gsdl3_path));
107 File [] sites = sites_dir.listFiles();
108 for (int i=0; i<sites.length; i++) {
109 File collect_dir = new File(Utility.getCollectDir(Gatherer.config.gsdl3_path, sites[i].getName()));
110 if (collect_dir.exists()) {
111 addCollectionsToModel(base_collection_model, collect_dir, sites[i].getName());
112 }
113 }
114 } else {
115 File gsdl_collection_directory = new File(Utility.getCollectDir(Gatherer.config.gsdl_path));
116 addCollectionsToModel(base_collection_model, gsdl_collection_directory, null);
117 }
118
119 // Sort the result.
120 Collections.sort(base_collection_model);
121 base_collection_model.add(0, new Item(null, Dictionary.get("NewCollectionPrompt.NewCollection")));
122
123 // Creation
124 JPanel content_pane = (JPanel) getContentPane();
125 content_pane.setOpaque(true);
126 JPanel upper_pane = new JPanel();
127 JLabel instructions_label = new JLabel();
128 Dictionary.setText(instructions_label, "NewCollectionPrompt.Instructions");
129 JPanel title_pane = new JPanel();
130 JLabel title_label = new JLabel();
131 Dictionary.setText(title_label, "CDM.General.Collection_Name");
132 title = new JTextField();
133 title.setPreferredSize(COMPONENT_SIZE);
134 Dictionary.setTooltip(title, "CDM.General.Collection_Name_Tooltip");
135 JPanel name_pane = new JPanel();
136 JLabel name_label = new JLabel();
137 Dictionary.setText(name_label, "NewCollectionPrompt.Collection_Name");
138
139 JPanel center_pane = new JPanel();
140 JPanel description_pane = new JPanel();
141 JLabel description_label = new JLabel();
142 Dictionary.setText(description_label, "NewCollectionPrompt.Collection_Description");
143 description = new JTextArea();
144 description.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
145 description.setForeground(Gatherer.config.getColor("coloring.editable_foreground", false));
146 description.setRows(5);
147 Dictionary.setTooltip(description, "CDM.General.Collection_Extra_Tooltip");
148
149 JPanel bottom_pane = new JPanel();
150 // Base Collection
151 JPanel base_collection_pane = new JPanel();
152 JLabel base_collection_label = new JLabel();
153 Dictionary.setText(base_collection_label, "NewCollectionPrompt.Base_Collection");
154 base_collection = new JComboBox(base_collection_model);
155 Dictionary.setTooltip(base_collection, "NewCollectionPrompt.Base_Collection_Tooltip");
156
157 JPanel button_pane = new JPanel();
158 create_button = new GLIButton();
159 create_button.setMnemonic(KeyEvent.VK_O);
160 Dictionary.setBoth(create_button, "General.OK", "General.OK_Tooltip");
161 JButton cancel_button = new GLIButton();
162 cancel_button.setMnemonic(KeyEvent.VK_C);
163 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
164 // Connection
165 cancel_button.addActionListener(new CancelListener());
166 create_button.addActionListener(new CreateListener());
167 description.addKeyListener(new ColorListener(description));
168 description.addKeyListener(new DescriptionListener());
169 title.addKeyListener(new ColorListener(title));
170
171 // Layout
172 title_pane.setLayout(new BorderLayout(5,0));
173 title_pane.add(title_label, BorderLayout.WEST);
174 title_pane.add(title, BorderLayout.CENTER);
175
176 upper_pane.setLayout(new GridLayout(2,1));
177 upper_pane.add(instructions_label);
178 upper_pane.add(title_pane);
179
180 description_pane.setLayout(new BorderLayout());
181 description_pane.add(description_label, BorderLayout.NORTH);
182 description_pane.add(new JScrollPane(description), BorderLayout.CENTER);
183
184 base_collection_pane.setLayout(new BorderLayout(5,0));
185 base_collection_pane.add(base_collection_label, BorderLayout.WEST);
186 base_collection_pane.add(base_collection, BorderLayout.CENTER);
187
188 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
189 center_pane.setLayout(new BorderLayout());
190 center_pane.add(description_pane, BorderLayout.CENTER);
191
192 bottom_pane.setLayout(new BorderLayout());
193 bottom_pane.add(base_collection_pane, BorderLayout.CENTER);
194 bottom_pane.add(button_pane, BorderLayout.SOUTH);
195
196 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
197 button_pane.setLayout(new GridLayout(1,2));
198 button_pane.add(create_button);
199 button_pane.add(cancel_button);
200
201 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
202 content_pane.setLayout(new BorderLayout());
203 content_pane.add(upper_pane, BorderLayout.NORTH);
204 content_pane.add(center_pane, BorderLayout.CENTER);
205 content_pane.add(bottom_pane, BorderLayout.SOUTH);
206 // Final dialog setup & positioning.
207 Dimension screen_size = Gatherer.config.screen_size;
208 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
209 setVisible(true);
210 }
211
212 public boolean isCancelled() {
213 return cancelled;
214 }
215
216 public File getBase() {
217 return base_final;
218 }
219
220 public String getDescription() {
221 return description_final;
222 }
223
224 /** 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.
225 * @return the filename as a String
226 */
227 public String getName() {
228 // Retrieve the first 8 non-whitespace characters of title_final.
229 StringBuffer name_buffer = new StringBuffer("");
230 int i = 0;
231 while(i < title_final.length() && name_buffer.length() < 8) {
232 char c = title_final.charAt(i);
233 // Arg. We need a few more tests than just whitespace
234 if(Character.isLetterOrDigit(c)) {
235 name_buffer.append(Character.toLowerCase(c));
236 }
237 i++;
238 }
239 // We need to ensure the filename is unique
240 int counter = 0;
241 StringBuffer new_name_buffer = new StringBuffer(name_buffer.toString());
242 while(filenameClashes(new_name_buffer.toString())) {
243 new_name_buffer = new StringBuffer(name_buffer.toString());
244 counter++;
245 String suffix = String.valueOf(counter);
246 // If we have to truncate the namestring so as to fit the suffix
247 if(suffix.length() + new_name_buffer.length() > 8) {
248 new_name_buffer.replace(new_name_buffer.length() - suffix.length(), new_name_buffer.length(), suffix);
249 }
250 // Or just append it if that isn't necessary
251 else {
252 new_name_buffer.append(suffix);
253 }
254
255 }
256 // All done
257 return new_name_buffer.toString();
258 }
259
260 private boolean filenameClashes(String filename) {
261 File collection_directory;
262 if (Gatherer.GS3) {
263 collection_directory = new File(Utility.getCollectDir(Gatherer.config.gsdl3_path, Gatherer.config.site_name));
264 } else {
265 collection_directory = new File(Utility.getCollectDir(Gatherer.config.gsdl_path));
266 }
267
268 File children[] = collection_directory.listFiles();
269 for(int i = 0; children != null && i < children.length; i++) {
270 if(children[i].getName().equals(filename)) {
271 return true;
272 }
273 }
274 return false;
275 }
276
277 public String getTitle() {
278 return title_final;
279 }
280
281 private void addCollectionsToModel(Vector base_collection_model, File collect_directory, String site) {
282 File[] possible_collections = collect_directory.listFiles();
283 for (int i = 0; possible_collections != null && i < possible_collections.length; i++) {
284 // If the directory has a etc/collect.cfg file then it looks like a collection
285 File collect_cfg_file = new File(possible_collections[i], Utility.CONFIG_FILE);
286 if (collect_cfg_file.exists()) {
287 // If the directory has a metadata/ then the collection can be used as a base
288 File metadata_directory = new File(possible_collections[i], Utility.META_DIR);
289 if (metadata_directory.exists()) {
290 // Add to model
291 BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
292 if (Gatherer.GS3 && site != null) {
293 collect_cfg.setSite(site);
294 }
295 Item item = new Item(possible_collections[i], collect_cfg);
296 if (!base_collection_model.contains(item)) {
297 base_collection_model.add(item);
298 }
299 }
300 }
301 }
302
303 }
304
305 private class CancelListener
306 implements ActionListener {
307 public void actionPerformed(ActionEvent event) {
308 cancelled = true;
309 self.dispose();
310 }
311 }
312
313 private class ColorListener
314 extends KeyAdapter {
315 private JTextComponent component1;
316 private JTextComponent component2;
317 public ColorListener(JTextComponent component) {
318 this.component1 = component;
319 this.component2 = null;
320 }
321 public ColorListener(JTextComponent component1, JTextComponent component2) {
322 this.component1 = component1;
323 this.component2 = component2;
324 }
325 public void keyPressed(KeyEvent event) {
326 component1.setForeground(Gatherer.config.getColor("coloring.editable_foreground", false));
327 component1.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
328 if(component2 != null) {
329 component2.setForeground(Gatherer.config.getColor("coloring.editable_foreground", false));
330 component2.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
331 }
332 }
333 }
334
335 private class CreateListener
336 implements ActionListener {
337
338 public void actionPerformed(ActionEvent event) {
339 // Validate.
340 title_final = title.getText();
341 if(title_final.length() == 0) {
342 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
343 title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
344 title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
345 return;
346 }
347 // 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
348 else {
349 if(titleClashes(title_final, null)) {
350 if(JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Clash"), Dictionary.get("General.Warning"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.NO_OPTION) {
351 title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
352 title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
353 return;
354 }
355 }
356 }
357
358 description_final = description.getText();
359 if(description_final.length() == 0) {
360 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Description_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
361 description.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
362 description.setBackground(Gatherer.config.getColor("coloring.error_background", false));
363 return;
364 }
365 // If we got this far there are no errors.
366 Item item_final = (Item) base_collection.getSelectedItem();
367 base_final = item_final.getFile();
368
369 cancelled = false;
370
371 self.dispose();
372 }
373 }
374
375 private class DescriptionListener
376 extends KeyAdapter {
377 public void keyPressed(KeyEvent event) {
378 if(event.getKeyCode() == KeyEvent.VK_TAB) {
379 event.consume();
380 base_collection.grabFocus();
381 }
382 }
383 }
384
385 private class Item
386 implements Comparable {
387 private BasicCollectionConfiguration config;
388 private File file;
389 private String name;
390 public Item(File file, BasicCollectionConfiguration config) {
391 this.config = config;
392 this.file = file;
393 this.name = null;
394 }
395 public Item(File file, String name) {
396 this.config = null;
397 this.file = file;
398 this.name = name;
399 }
400 public int compareTo(Object other) {
401 return toString().toLowerCase().compareTo(other.toString().toLowerCase());
402 }
403 public boolean equals(Object other) {
404 return compareTo(other) == 0;
405 }
406 public File getFile() {
407 return file;
408 }
409 public String toString() {
410 if(name == null && config != null) {
411 name = config.toString();
412 }
413 return name;
414 }
415 }
416}
417
418
419
Note: See TracBrowser for help on using the repository browser.