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
RevLine 
[4932]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.*;
[8236]34import org.greenstone.gatherer.DebugStream;
[5590]35import org.greenstone.gatherer.Dictionary;
[4932]36import org.greenstone.gatherer.Gatherer;
[6318]37import org.greenstone.gatherer.gui.GLIButton;
[9161]38import org.greenstone.gatherer.util.CheckList;
[10011]39import org.greenstone.gatherer.util.JarTools;
[4932]40import org.w3c.dom.*;
[9161]41
42
[4932]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
[9161]48 extends DOMProxyListModel
49{
50 static final private Dimension FIELD_SIZE = new Dimension(200, 30);
[4932]51
52 private Control controls;
53 private DOMProxyListModel model;
54 private SubcollectionIndex default_index;
55
[9161]56
[4932]57 /** Constructor. */
[9161]58 public SubcollectionIndexManager(Element subindexes)
59 {
[4932]60 super(subindexes, CollectionConfiguration.INDEX_ELEMENT, new SubcollectionIndex());
[8236]61 DebugStream.println("SubcollectionIndexManager: " + getSize() + " subcollection indexes parsed.");
[12283]62 this.model = this;
[9161]63
[4932]64 // Parse and retrieve the default index
65 NodeList default_index_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
[9161]66 if (default_index_elements.getLength() > 0) {
67 default_index = new SubcollectionIndex((Element) default_index_elements.item(0));
[4932]68 }
69 }
70
[9161]71
[4932]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 */
[9161]77 private void addSubcollectionIndex(SubcollectionIndex subcollection_index)
78 {
79 if (!contains(subcollection_index)) {
[12283]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);
[9161]84 add(getSize(), subcollection_index);
[4932]85 Gatherer.c_man.configurationChanged();
86 }
87 }
88
[9161]89
90 public void destroy()
91 {
92 if (controls != null) {
[4932]93 controls.destroy();
94 controls = null;
95 }
96 default_index = null;
97 model = null;
98 }
99
[9161]100
101 public Control getControls()
102 {
103 if (controls == null) {
104 controls = new SubcollectionIndexControls();
[4932]105 }
106 return controls;
107 }
108
[9161]109
110 /** Method to get all of the subindexes set.
111 * @return an ArrayList containing all the defined indexes
[4932]112 */
[9161]113 public ArrayList getSubcollectionIndexes()
114 {
115 return children();
116 }
117
[12283]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 }
[9161]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));
[4932]141 }
[9161]142
143 // Attempt to move the subcollection index down
[4932]144 else {
[9161]145 // Check it's not already at the bottom
146 if (position == (getSize()) - 1) {
147 return position;
148 }
[4932]149
[9161]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));
[4932]153 }
154
[9161]155 // Schedule the collection for saving
156 Gatherer.c_man.configurationChanged();
157 return new_position;
[4932]158 }
159
[9161]160
161 /** Method to remove a certain subcollection index. */
162 private void removeSubcollectionIndex(SubcollectionIndex subcollection_index)
163 {
164 if (subcollection_index != null) {
[4932]165 // Remove any current metadata from this index
[12283]166 CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + subcollection_index.getID());
[9161]167
[4932]168 // Check if the index removed happens to be the default index
[9161]169 if (default_index != null && default_index.equals(subcollection_index)) {
[12283]170 setDefault(null);
[4932]171 }
[12283]172
[4932]173 // Remove the index
[9161]174 remove(subcollection_index);
[4932]175 Gatherer.c_man.configurationChanged();
176 }
177 }
[5590]178
[9161]179
[4932]180 /** Method to remove all of the subindexes that contain a certain subcollection.
[6770]181 * @param subcollection the Subcollection that has been removed
[4932]182 * @see org.greenstone.gatherer.cdm.Subcollection
183 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
184 */
[9161]185 public void removeSubcollectionIndexes(Subcollection subcollection)
186 {
[4932]187 String subcollection_name = subcollection.getName();
188 int size = getSize();
189 for(int i = size - 1; i >= 0; i--) {
[9161]190 SubcollectionIndex subcollection_index = (SubcollectionIndex) getElementAt(i);
191 if (subcollection_index.getSources().contains(subcollection_name)) {
192 removeSubcollectionIndex(subcollection_index);
[4932]193 }
194 }
195 }
196
[12283]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 }
[9161]207
[12283]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
[4932]218 /** Method to set the default subcollection index.
[6770]219 * @param index The <strong>SubcollectionIndex</strong> to use as the default index.
[5590]220 * @see org.greenstone.gatherer.Gatherer
221 * @see org.greenstone.gatherer.collection.CollectionManager
[6770]222 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
[5590]223 */
[12283]224 private void setDefault(SubcollectionIndex subcollection_index)
[9161]225 {
226 if (subcollection_index != null) {
227 if (default_index == null) {
[4932]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);
[9161]232 if (target_node != null) {
[4932]233 root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node);
234 }
235 else {
236 root.getOwnerDocument().getDocumentElement().appendChild(default_index_element);
237 }
[9161]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();
[4932]248 }
249
[9161]250
251 /** This class creates a set of controls for editing the indexes. */
252 private class SubcollectionIndexControls
[4932]253 extends JPanel
[9161]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;
[4932]262 private JButton set_default_button;
[9161]263 private JList subcollection_index_list;
264 private JTextField subcollection_index_name_textfield;
[4932]265
[9161]266
267 /** Constructor.
268 */
269 public SubcollectionIndexControls()
270 {
[4932]271 super();
272
[9161]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 }
[5590]278
[9161]279 // Creation
280 JPanel assigned_indexes_pane = new JPanel();
[12123]281 JLabel index_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Subindexes"));
282 subcollection_index_list = new JList(model);
[9161]283 subcollection_index_list.setCellRenderer(new SubcollectionIndexListCellRenderer());
284 subcollection_index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
285 subcollection_index_list.setVisibleRowCount(2);
[4932]286
[9161]287 JPanel movement_pane = new JPanel();
[12123]288 move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
[9562]289 move_up_button.setEnabled(false);
[12123]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"));
[9562]292 move_down_button.setEnabled(false);
[12123]293
294 set_default_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex_Tooltip"));
[9161]295 set_default_button.setEnabled(false);
[12123]296
[9161]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();
[4932]302
[12123]303 JLabel source_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Source"));
304
[9161]305 source_list = new CheckList(false);
306 source_list.setListData(sources);
[12123]307 source_list.setToolTipText(Dictionary.get("CDM.SubcollectionIndexManager.Source_Tooltip"));
308
[9161]309 JPanel button_pane = new JPanel();
[12123]310 add_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex_Tooltip"));
[9161]311 add_button.setEnabled(false);
[12123]312
313 remove_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex_Tooltip"));
[9161]314 remove_button.setEnabled(false);
[12123]315
316 replace_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex_Tooltip"));
[9161]317 replace_button.setEnabled(false);
[12123]318
[9161]319 // Listeners
320 add_button.addActionListener(new AddListener());
[10237]321 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]322 move_down_button.addActionListener(new MoveListener(false));
[10237]323 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]324 move_up_button.addActionListener(new MoveListener(true));
[10237]325 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]326 remove_button.addActionListener(new RemoveListener());
[10237]327 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]328 replace_button.addActionListener(new ReplaceListener());
[10237]329 replace_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]330 set_default_button.addActionListener(new SetDefaultListener());
[10237]331 set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[12283]332 subcollection_index_list.addListSelectionListener(new AssignedListListener());
[9161]333 source_list.addListSelectionListener(new SourceListListener());
334
[4932]335 // Layout
[9161]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);
[4932]341
[9161]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);
[4932]347
[9161]348 labels_pane.setLayout(new BorderLayout());
349 labels_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
350 labels_pane.add(source_label, BorderLayout.CENTER);
[4932]351
[9161]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);
[4932]358
[9161]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);
[5236]363
[9161]364 index_pane.setLayout(new BorderLayout());
365 index_pane.add(details_pane, BorderLayout.CENTER);
366 index_pane.add(button_pane, BorderLayout.SOUTH);
[5212]367
[9161]368 content_pane.setLayout(new BorderLayout());
369 content_pane.add(assigned_indexes_pane, BorderLayout.NORTH);
370 content_pane.add(index_pane, BorderLayout.CENTER);
371
[4932]372 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
373 setLayout(new BorderLayout());
[9161]374 add(content_pane, BorderLayout.CENTER);
[4932]375 }
376
[9161]377
378 public void destroy()
379 {
[5903]380 }
381
[9161]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
[12283]396 clearControls();
397
[4932]398 }
399
[9161]400
[12283]401 public void loseFocus() {
[4932]402 }
403
[12283]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);
[9161]413
[12283]414 }
415
[9161]416 private void updateControlsWithSelectedIndex()
417 {
418 SubcollectionIndex selected_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
419 if (selected_index == null) {
[12283]420 source_list.clearTicked();
[9161]421 return;
422 }
423
424 // Display the selected subcollection index's sources
[9200]425 source_list.clearTicked();
426 source_list.setTickedObjects(selected_index.getSources().toArray());
[4932]427 }
428
[9161]429
[12283]430 private void validateButtons() {
431
[9161]432 boolean add_enabled = false;
433 boolean replace_enabled = false;
434
435 // Can't add a new index if no sources are selected
[12283]436 if (!source_list.isNothingTicked()) {
437 ArrayList sources = source_list.getTicked();
[9161]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
[12283]441 if (!model.contains(subcollection_index)) {
[9161]442 add_enabled = true;
[12283]443 if (!subcollection_index_list.isSelectionEmpty()) {
[9161]444 replace_enabled = true;
445 }
446 }
[4932]447 }
[9161]448
449 // We should now know the add_button state
450 add_button.setEnabled(add_enabled);
451 replace_button.setEnabled(replace_enabled);
[4932]452 }
453
[9161]454
455 private class AddListener
[12283]456 implements ActionListener {
457
[9161]458 public void actionPerformed(ActionEvent event)
459 {
[12283]460 if (!source_list.isNothingTicked()) {
[9200]461 ArrayList sources = source_list.getTicked();
[9161]462 SubcollectionIndex subcollection_index = new SubcollectionIndex(sources.toArray());
463 addSubcollectionIndex(subcollection_index);
[12283]464 clearControls();
[9161]465 }
[4932]466 }
467 }
468
[9161]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;
[4932]478 }
[9161]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);
[4932]488 }
489 }
490 }
491
[9161]492 private class RemoveListener
493 implements ActionListener
494 {
[12283]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);
[4932]500 }
501 }
[9161]502 }
[4932]503
[9161]504
505 private class ReplaceListener
[12283]506 implements ActionListener {
507
508 public void actionPerformed(ActionEvent event) {
509
510 if (subcollection_index_list.isSelectionEmpty()|| source_list.isNothingTicked()) {
[9161]511 // This should never happen, but just in case...
512 replace_button.setEnabled(false);
513 return;
[4932]514 }
[12283]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);
[9161]519 }
520 }
521
522
523 private class SetDefaultListener
[12283]524 implements ActionListener {
525
[9161]526 public void actionPerformed(ActionEvent event)
527 {
528 SubcollectionIndex subcollection_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
529 if (subcollection_index != null) {
[12283]530 setDefault(subcollection_index);
[9161]531 // This should cause a repaint of just the desired row
532 subcollection_index_list.setSelectedValue(subcollection_index, true);
[4932]533 }
[9161]534 set_default_button.setEnabled(false);
[4932]535 }
536 }
[5236]537
538
[9161]539 private class SourceListListener
[12283]540 implements ListSelectionListener {
541
542 public void valueChanged(ListSelectionEvent event) {
543 if (event.getValueIsAdjusting()) {
544 return;
545 }
546 validateButtons();
[9161]547 }
548 }
549
550
[12283]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
[9161]557 if (event.getValueIsAdjusting()) {
558 return;
[5236]559 }
[9161]560
[12283]561 if (subcollection_index_list.isSelectionEmpty()) {
562 clearControls();
563 return;
564 }
565
[9161]566 int i = subcollection_index_list.getSelectedIndex();
567 int size = subcollection_index_list.getModel().getSize();
[12283]568
[9161]569 // Enable the buttons appropriately
570 remove_button.setEnabled(true);
[12283]571 replace_button.setEnabled(false);
572 add_button.setEnabled(false);
[9161]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();
[5236]590 }
591 }
[9161]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 }
[4932]606 }
607}
Note: See TracBrowser for help on using the repository browser.