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

Last change on this file since 13531 was 13195, checked in by kjdon, 18 years ago

quan's changes to remove blue borders around buttons and comboboxes on macs

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