source: trunk/gli/src/org/greenstone/gatherer/cdm/SubcollectionIndexManager.java@ 12467

Last change on this file since 12467 was 12283, checked in by kjdon, 18 years ago

made this more like LanguageManager. A bit more simple.

  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 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 Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 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.cdm;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.util.*;
32import javax.swing.*;
33import javax.swing.event.*;
34import org.greenstone.gatherer.DebugStream;
35import org.greenstone.gatherer.Dictionary;
36import org.greenstone.gatherer.Gatherer;
37import org.greenstone.gatherer.gui.GLIButton;
38import org.greenstone.gatherer.util.CheckList;
39import org.greenstone.gatherer.util.JarTools;
40import org.w3c.dom.*;
41
42
43/** This class maintains a list of indexes partitions for the purpose of defining subcollections.
44 * @author John Thompson, Greenstone Digital Library, University of Waikato
45 * @version 2.4
46 */
47public class SubcollectionIndexManager
48 extends DOMProxyListModel
49{
50 static final private Dimension FIELD_SIZE = new Dimension(200, 30);
51
52 private Control controls;
53 private DOMProxyListModel model;
54 private SubcollectionIndex default_index;
55
56
57 /** Constructor. */
58 public SubcollectionIndexManager(Element subindexes)
59 {
60 super(subindexes, CollectionConfiguration.INDEX_ELEMENT, new SubcollectionIndex());
61 DebugStream.println("SubcollectionIndexManager: " + getSize() + " subcollection indexes parsed.");
62 this.model = this;
63
64 // Parse and retrieve the default index
65 NodeList default_index_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
66 if (default_index_elements.getLength() > 0) {
67 default_index = new SubcollectionIndex((Element) default_index_elements.item(0));
68 }
69 }
70
71
72 /** Method to add a subindex.
73 * @param subindex a SubcollectionIndex
74 * @see org.greenstone.gatherer.Gatherer
75 * @see org.greenstone.gatherer.collection.CollectionManager
76 */
77 private void addSubcollectionIndex(SubcollectionIndex subcollection_index)
78 {
79 if (!contains(subcollection_index)) {
80 // add a pseudo metadata
81 CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + subcollection_index.getID());
82 metadatum.setValue(subcollection_index.getID());
83 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
84 add(getSize(), subcollection_index);
85 Gatherer.c_man.configurationChanged();
86 }
87 }
88
89
90 public void destroy()
91 {
92 if (controls != null) {
93 controls.destroy();
94 controls = null;
95 }
96 default_index = null;
97 model = null;
98 }
99
100
101 public Control getControls()
102 {
103 if (controls == null) {
104 controls = new SubcollectionIndexControls();
105 }
106 return controls;
107 }
108
109
110 /** Method to get all of the subindexes set.
111 * @return an ArrayList containing all the defined indexes
112 */
113 public ArrayList getSubcollectionIndexes()
114 {
115 return children();
116 }
117
118 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
119 * @param mode the new mode as an int
120 */
121 public void modeChanged(int mode) {
122
123 }
124
125 private int moveSubcollectionIndex(SubcollectionIndex subcollection_index, boolean move_up)
126 {
127 // Determine the current position of the subcollection index
128 int position = indexOf(subcollection_index);
129 int new_position;
130
131 // Attempt to move the subcollection index up
132 if (move_up) {
133 // Check it's not already at the top
134 if (position == 0) {
135 return position;
136 }
137
138 // This automatically removes the index first, as an Element can only exist once in a particular document
139 new_position = position - 1;
140 addBefore(subcollection_index, (SubcollectionIndex) getElementAt(new_position));
141 }
142
143 // Attempt to move the subcollection index down
144 else {
145 // Check it's not already at the bottom
146 if (position == (getSize()) - 1) {
147 return position;
148 }
149
150 // This automatically removes the index first, as an Element can only exist once in a particular document
151 new_position = position + 1;
152 addAfter(subcollection_index, (SubcollectionIndex) getElementAt(new_position));
153 }
154
155 // Schedule the collection for saving
156 Gatherer.c_man.configurationChanged();
157 return new_position;
158 }
159
160
161 /** Method to remove a certain subcollection index. */
162 private void removeSubcollectionIndex(SubcollectionIndex subcollection_index)
163 {
164 if (subcollection_index != null) {
165 // Remove any current metadata from this index
166 CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + subcollection_index.getID());
167
168 // Check if the index removed happens to be the default index
169 if (default_index != null && default_index.equals(subcollection_index)) {
170 setDefault(null);
171 }
172
173 // Remove the index
174 remove(subcollection_index);
175 Gatherer.c_man.configurationChanged();
176 }
177 }
178
179
180 /** Method to remove all of the subindexes that contain a certain subcollection.
181 * @param subcollection the Subcollection that has been removed
182 * @see org.greenstone.gatherer.cdm.Subcollection
183 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
184 */
185 public void removeSubcollectionIndexes(Subcollection subcollection)
186 {
187 String subcollection_name = subcollection.getName();
188 int size = getSize();
189 for(int i = size - 1; i >= 0; i--) {
190 SubcollectionIndex subcollection_index = (SubcollectionIndex) getElementAt(i);
191 if (subcollection_index.getSources().contains(subcollection_name)) {
192 removeSubcollectionIndex(subcollection_index);
193 }
194 }
195 }
196
197 private void replaceSubcollectionIndex(SubcollectionIndex old_subcollection, SubcollectionIndex new_subcollection) {
198 // Remove old collection meta
199 CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + old_subcollection.getID());
200 // Add new one
201 CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + new_subcollection.getID());
202 metadatum.setValue(new_subcollection.getID());
203 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
204 if(default_index != null && default_index.equals(old_subcollection)) {
205 setDefault(new_subcollection);
206 }
207
208 // get the position of the old one
209 int position = indexOf(old_subcollection);
210 remove(old_subcollection);
211 add(position, new_subcollection);
212
213 // Schedule the collection for saving
214 Gatherer.c_man.configurationChanged();
215
216 }
217
218 /** Method to set the default subcollection index.
219 * @param index The <strong>SubcollectionIndex</strong> to use as the default index.
220 * @see org.greenstone.gatherer.Gatherer
221 * @see org.greenstone.gatherer.collection.CollectionManager
222 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
223 */
224 private void setDefault(SubcollectionIndex subcollection_index)
225 {
226 if (subcollection_index != null) {
227 if (default_index == null) {
228 // Create the default index element, and place immediately after indexes element.
229 Element default_index_element = root.getOwnerDocument().createElement(CollectionConfiguration.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
230 default_index = new SubcollectionIndex(default_index_element);
231 Node target_node = CollectionConfiguration.findInsertionPoint(default_index_element);
232 if (target_node != null) {
233 root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node);
234 }
235 else {
236 root.getOwnerDocument().getDocumentElement().appendChild(default_index_element);
237 }
238 }
239 default_index.setAssigned(true);
240 default_index.setSources(subcollection_index.getSources());
241 }
242 else {
243 if (default_index != null) {
244 default_index.setAssigned(false);
245 }
246 }
247 Gatherer.c_man.configurationChanged();
248 }
249
250
251 /** This class creates a set of controls for editing the indexes. */
252 private class SubcollectionIndexControls
253 extends JPanel
254 implements Control
255 {
256 private CheckList source_list;
257 private JButton add_button;
258 private JButton move_down_button;
259 private JButton move_up_button;
260 private JButton remove_button;
261 private JButton replace_button;
262 private JButton set_default_button;
263 private JList subcollection_index_list;
264 private JTextField subcollection_index_name_textfield;
265
266
267 /** Constructor.
268 */
269 public SubcollectionIndexControls()
270 {
271 super();
272
273 ArrayList sources = new ArrayList();
274 ListModel source_model = CollectionDesignManager.subcollection_manager;
275 for (int i = 0; i < source_model.getSize(); i++) {
276 sources.add(source_model.getElementAt(i));
277 }
278
279 // Creation
280 JPanel assigned_indexes_pane = new JPanel();
281 JLabel index_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Subindexes"));
282 subcollection_index_list = new JList(model);
283 subcollection_index_list.setCellRenderer(new SubcollectionIndexListCellRenderer());
284 subcollection_index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
285 subcollection_index_list.setVisibleRowCount(2);
286
287 JPanel movement_pane = new JPanel();
288 move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
289 move_up_button.setEnabled(false);
290
291 move_down_button = new GLIButton(Dictionary.get("CDM.Move.Move_Down"), JarTools.getImage("arrow-down.gif"), Dictionary.get("CDM.Move.Move_Down_Tooltip"));
292 move_down_button.setEnabled(false);
293
294 set_default_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex_Tooltip"));
295 set_default_button.setEnabled(false);
296
297 JPanel index_pane = new JPanel();
298 JPanel details_pane = new JPanel();
299 JPanel labels_pane = new JPanel();
300 JPanel boxes_pane = new JPanel();
301 JPanel content_pane = new JPanel();
302
303 JLabel source_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Source"));
304
305 source_list = new CheckList(false);
306 source_list.setListData(sources);
307 source_list.setToolTipText(Dictionary.get("CDM.SubcollectionIndexManager.Source_Tooltip"));
308
309 JPanel button_pane = new JPanel();
310 add_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex_Tooltip"));
311 add_button.setEnabled(false);
312
313 remove_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex_Tooltip"));
314 remove_button.setEnabled(false);
315
316 replace_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex_Tooltip"));
317 replace_button.setEnabled(false);
318
319 // Listeners
320 add_button.addActionListener(new AddListener());
321 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
322 move_down_button.addActionListener(new MoveListener(false));
323 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
324 move_up_button.addActionListener(new MoveListener(true));
325 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
326 remove_button.addActionListener(new RemoveListener());
327 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
328 replace_button.addActionListener(new ReplaceListener());
329 replace_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
330 set_default_button.addActionListener(new SetDefaultListener());
331 set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
332 subcollection_index_list.addListSelectionListener(new AssignedListListener());
333 source_list.addListSelectionListener(new SourceListListener());
334
335 // Layout
336 movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
337 movement_pane.setLayout(new GridLayout(3,1));
338 movement_pane.add(move_up_button);
339 movement_pane.add(move_down_button);
340 movement_pane.add(set_default_button);
341
342 assigned_indexes_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
343 assigned_indexes_pane.setLayout(new BorderLayout());
344 assigned_indexes_pane.add(index_label, BorderLayout.NORTH);
345 assigned_indexes_pane.add(new JScrollPane(subcollection_index_list), BorderLayout.CENTER);
346 assigned_indexes_pane.add(movement_pane, BorderLayout.EAST);
347
348 labels_pane.setLayout(new BorderLayout());
349 labels_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
350 labels_pane.add(source_label, BorderLayout.CENTER);
351
352 boxes_pane.setLayout(new BorderLayout());
353 boxes_pane.add(new JScrollPane(source_list), BorderLayout.CENTER);
354
355 details_pane.setLayout(new BorderLayout());
356 details_pane.add(labels_pane, BorderLayout.WEST);
357 details_pane.add(boxes_pane, BorderLayout.CENTER);
358
359 button_pane.setLayout(new GridLayout(1,3));
360 button_pane.add(add_button);
361 button_pane.add(replace_button);
362 button_pane.add(remove_button);
363
364 index_pane.setLayout(new BorderLayout());
365 index_pane.add(details_pane, BorderLayout.CENTER);
366 index_pane.add(button_pane, BorderLayout.SOUTH);
367
368 content_pane.setLayout(new BorderLayout());
369 content_pane.add(assigned_indexes_pane, BorderLayout.NORTH);
370 content_pane.add(index_pane, BorderLayout.CENTER);
371
372 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
373 setLayout(new BorderLayout());
374 add(content_pane, BorderLayout.CENTER);
375 }
376
377
378 public void destroy()
379 {
380 }
381
382
383 public void gainFocus()
384 {
385 // Reload the source list
386 ArrayList sources = new ArrayList();
387 ListModel source_model = CollectionDesignManager.subcollection_manager;
388 for (int i = 0; i < source_model.getSize(); i++) {
389 sources.add(source_model.getElementAt(i));
390 }
391 source_list.setListData(sources);
392
393 // Refresh the subcollection index list
394 subcollection_index_list.updateUI();
395
396 clearControls();
397
398 }
399
400
401 public void loseFocus() {
402 }
403
404 private void clearControls() {
405 subcollection_index_list.clearSelection();
406 source_list.clearTicked();
407 add_button.setEnabled(false);
408 remove_button.setEnabled(false);
409 replace_button.setEnabled(false);
410 set_default_button.setEnabled(false);
411 move_down_button.setEnabled(false);
412 move_up_button.setEnabled(false);
413
414 }
415
416 private void updateControlsWithSelectedIndex()
417 {
418 SubcollectionIndex selected_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
419 if (selected_index == null) {
420 source_list.clearTicked();
421 return;
422 }
423
424 // Display the selected subcollection index's sources
425 source_list.clearTicked();
426 source_list.setTickedObjects(selected_index.getSources().toArray());
427 }
428
429
430 private void validateButtons() {
431
432 boolean add_enabled = false;
433 boolean replace_enabled = false;
434
435 // Can't add a new index if no sources are selected
436 if (!source_list.isNothingTicked()) {
437 ArrayList sources = source_list.getTicked();
438 SubcollectionIndex subcollection_index = new SubcollectionIndex(sources.toArray());
439
440 // Subcollection index already exists: can't add, but can replace if the name has changed
441 if (!model.contains(subcollection_index)) {
442 add_enabled = true;
443 if (!subcollection_index_list.isSelectionEmpty()) {
444 replace_enabled = true;
445 }
446 }
447 }
448
449 // We should now know the add_button state
450 add_button.setEnabled(add_enabled);
451 replace_button.setEnabled(replace_enabled);
452 }
453
454
455 private class AddListener
456 implements ActionListener {
457
458 public void actionPerformed(ActionEvent event)
459 {
460 if (!source_list.isNothingTicked()) {
461 ArrayList sources = source_list.getTicked();
462 SubcollectionIndex subcollection_index = new SubcollectionIndex(sources.toArray());
463 addSubcollectionIndex(subcollection_index);
464 clearControls();
465 }
466 }
467 }
468
469
470 private class MoveListener
471 implements ActionListener
472 {
473 private boolean move_up;
474
475 public MoveListener(boolean move_up)
476 {
477 this.move_up = move_up;
478 }
479
480 public void actionPerformed(ActionEvent event)
481 {
482 // Retrieve the selected subcollection index
483 SubcollectionIndex subcollection_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
484 if (subcollection_index != null) {
485 int new_position = moveSubcollectionIndex(subcollection_index, move_up);
486 // Ensure the subcollection index that moved is still selected
487 subcollection_index_list.setSelectedIndex(new_position);
488 }
489 }
490 }
491
492 private class RemoveListener
493 implements ActionListener
494 {
495 public void actionPerformed(ActionEvent event) {
496
497 SubcollectionIndex delete_me = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
498 if (delete_me != null) {
499 removeSubcollectionIndex(delete_me);
500 }
501 }
502 }
503
504
505 private class ReplaceListener
506 implements ActionListener {
507
508 public void actionPerformed(ActionEvent event) {
509
510 if (subcollection_index_list.isSelectionEmpty()|| source_list.isNothingTicked()) {
511 // This should never happen, but just in case...
512 replace_button.setEnabled(false);
513 return;
514 }
515 SubcollectionIndex old_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
516 ArrayList sources = source_list.getTicked();
517 SubcollectionIndex new_index = new SubcollectionIndex(sources.toArray());
518 replaceSubcollectionIndex(old_index, new_index);
519 }
520 }
521
522
523 private class SetDefaultListener
524 implements ActionListener {
525
526 public void actionPerformed(ActionEvent event)
527 {
528 SubcollectionIndex subcollection_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
529 if (subcollection_index != null) {
530 setDefault(subcollection_index);
531 // This should cause a repaint of just the desired row
532 subcollection_index_list.setSelectedValue(subcollection_index, true);
533 }
534 set_default_button.setEnabled(false);
535 }
536 }
537
538
539 private class SourceListListener
540 implements ListSelectionListener {
541
542 public void valueChanged(ListSelectionEvent event) {
543 if (event.getValueIsAdjusting()) {
544 return;
545 }
546 validateButtons();
547 }
548 }
549
550
551 /** Listens for selections within the assigned subcollection indexes list */
552 private class AssignedListListener
553 implements ListSelectionListener {
554
555 public void valueChanged(ListSelectionEvent event) {
556
557 if (event.getValueIsAdjusting()) {
558 return;
559 }
560
561 if (subcollection_index_list.isSelectionEmpty()) {
562 clearControls();
563 return;
564 }
565
566 int i = subcollection_index_list.getSelectedIndex();
567 int size = subcollection_index_list.getModel().getSize();
568
569 // Enable the buttons appropriately
570 remove_button.setEnabled(true);
571 replace_button.setEnabled(false);
572 add_button.setEnabled(false);
573 SubcollectionIndex selected_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
574 set_default_button.setEnabled(default_index == null || !default_index.equals(selected_index));
575 if (i > 0) {
576 move_up_button.setEnabled(true);
577 }
578 else {
579 move_up_button.setEnabled(false);
580 }
581 if (i < size-1){
582 move_down_button.setEnabled(true);
583 }
584 else {
585 move_down_button.setEnabled(false);
586 }
587
588 // Need to fill in the rest of the bits
589 updateControlsWithSelectedIndex();
590 }
591 }
592
593
594 private class SubcollectionIndexListCellRenderer
595 extends DefaultListCellRenderer
596 {
597 /** Return a component that has been configured to display the specified value. */
598 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
599 JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
600 if (default_index != null && default_index.equals(value)) {
601 component.setText(component.getText() + " " + Dictionary.get("CDM.SubcollectionIndexManager.Default_Partition_Indicator"));
602 }
603 return component;
604 }
605 }
606 }
607}
Note: See TracBrowser for help on using the repository browser.