Changeset 12083


Ignore:
Timestamp:
2006-07-07T12:20:56+12:00 (18 years ago)
Author:
kjdon
Message:

moved level stuff out of this. the index specification parts are moved to a popup - click new index and get a popup window

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/cdm/IndexManager.java

    r11905 r12083  
    3939import org.greenstone.gatherer.gui.GComboBox;
    4040import org.greenstone.gatherer.gui.GLIButton;
     41import org.greenstone.gatherer.gui.ModalDialog;
    4142import org.greenstone.gatherer.metadata.MetadataElement;
    4243import org.greenstone.gatherer.metadata.MetadataSetManager;
     
    5051 */
    5152public class IndexManager
    52     extends DOMProxyListModel {
    53 
    54     static final private Dimension FIELD_SIZE = new Dimension(200,30);
    55 
    56     static final private String ALLFIELDS = "allfields";
    57     /** The controls for editing the indexes. */
    58     private Control controls = null;
    59     /** A model of the levels, also based on the DOM. */
    60     private DOMProxyListModel levels_model = null;
     53    extends DOMProxyListModel
     54    implements BuildTypeManager.BuildTypeListener {
     55
    6156    /** A reference to ourselves so our inner methods have access. */
    62     private DOMProxyListModel model = null;
     57    private DOMProxyListModel index_model = null;
    6358    /** The default index. */
    6459    private Index default_index = null;
    6560
    66     /** Constructor. */
    67     public IndexManager(Element indexes) {
     61    private Control controls = null;
     62    private String build_type = null;
     63   
     64    static final private Dimension FIELD_SIZE = new Dimension(200,30);
     65    static final private String ALLFIELDS = "allfields";
     66
     67    static final private Dimension PROMPT_SIZE = new Dimension(400,400);
     68    public IndexManager(Element indexes, String current_build_type) {
     69
    6870    super(indexes, CollectionConfiguration.INDEX_ELEMENT, new Index());
    6971    DebugStream.println("IndexManager: " + getSize() + " indexes parsed.");
    70     model = this;
     72    index_model = this;
     73
    7174    // Parse and retrieve the default index
    7275    NodeList default_index_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.INDEX_DEFAULT_ELEMENT);
     
    7477        default_index = new Index((Element)default_index_elements.item(0));
    7578    }
    76     // Parse and retrieve the levels element
    77     Element levels_element = CollectionDesignManager.collect_config.getLevels();
    78     levels_model = new DOMProxyListModel(levels_element, CollectionConfiguration.CONTENT_ELEMENT, new Level());
    79     DebugStream.println(" + " + levels_model.getSize() + " levels parsed.");
     79    build_type = current_build_type;
    8080    }
    8181
     
    107107    }
    108108
    109     private void addLevel(Level level, CollectionMeta metadatum) {
    110     if(!levels_model.contains(level)) {
    111         CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
    112         // Retrieve the currently last level
    113         if(levels_model.getSize() > 0) {
    114         Level last_level = (Level)levels_model.getElementAt(levels_model.getSize() - 1);
    115         levels_model.addAfter(level, last_level);
    116         }
    117         else {
    118         levels_model.add(level);
    119         }
    120         Gatherer.c_man.configurationChanged();
    121     }
    122     else {
    123         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.IndexManager.Level_Exists"), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
    124     }
    125     }
    126 
    127     public void destroy() {
    128     if(controls != null) {
    129         controls.destroy();
    130         controls = null;
    131     }
    132     default_index = null;
    133     model = null;
    134     }
    135 
    136     /** Method to acquire the controls for editing the indexes.
    137      * @return the Control
    138      */
     109    public void buildTypeChanged(String new_build_type) {
     110    if (build_type.equals(new_build_type)) {
     111        return;
     112    }
     113    // we don;t care about this if old or new is not MG as MGPP and
     114    // Lucene have the same index specification
     115    if (!build_type.equals(BuildTypeManager.BUILD_TYPE_MG) && !new_build_type.equals(BuildTypeManager.BUILD_TYPE_MG)) {
     116        return;
     117    }
     118    boolean mg_to_mgpp = true;
     119    if (new_build_type.equals(BuildTypeManager.BUILD_TYPE_MG)) {
     120        mg_to_mgpp = false;
     121    }
     122    build_type  = new_build_type;
     123    if (mg_to_mgpp) {
     124        changeToMGPPIndexes();
     125    } else {
     126        changeToMGIndexes();
     127    }
     128    // its really hard to transfer defaults between mgpp/lucene and mg indexes, so we'll just set the first one to be the default
     129    Index first_index = (Index) getElementAt(0);
     130    setDefault(first_index);
     131    first_index = null;
     132    }
     133   
     134    private void changeToMGIndexes() {
     135    Element mgpp_element = root;
     136    // Retrieve and assign MG element and default index element
     137    Element mg_element = CollectionDesignManager.collect_config.getMGIndexes();
     138    mg_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
     139    NodeList indexes = mg_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
     140    if(indexes.getLength() != 0) {
     141        //just reinstate what we had previously
     142        setRoot(mg_element);
     143    } else {
     144        // If mg element has no indexes, and the current mgpp index includes a text one, then generate text indexes for each of the registered levels.
     145        Index index = getIndex(CollectionConfiguration.TEXT_STR);
     146        if(index != null) {
     147        // Replace mgpp element with mg element
     148        setRoot(mg_element);
     149        ArrayList levels = CollectionDesignManager.index_manager.getLevels();
     150        int level_size = levels.size();
     151        for(int i = 0; i < level_size; i++) {
     152            Level level = (Level) levels.get(i);
     153            Index new_index = new Index(level.getLevel(), index.getSources());
     154            // Try to retrieve existing metadatum
     155            String source_str = new_index.getID();
     156            CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + source_str, false);
     157            // If no metadata was found, add new pseudo metadata using the id
     158            if(metadatum == null) {
     159            metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source_str);
     160            metadatum.setAssigned(true);
     161            metadatum.setValue(source_str);
     162            }
     163            // If it was found, ensure it is assigned
     164            else {
     165            metadatum.setAssigned(true);
     166            }
     167            source_str = null;
     168            addIndex(new_index, metadatum);
     169            new_index = null;
     170            level = null;
     171        }
     172        }
     173    }
     174   
     175    // Unassign mgpp element
     176    mgpp_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
     177    mgpp_element = null;
     178   
     179    }
     180
     181    private void changeToMGPPIndexes() {
     182    Element mg_element = root;
     183    // Retrieve and assign the MGPP indexes element.
     184    Element mgpp_element = CollectionDesignManager.collect_config.getMGPPIndexes();
     185    mgpp_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
     186    NodeList indexes = mgpp_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
     187    if(indexes.getLength() != 0) {
     188        // we just reinstate the indexes we had before the change
     189        setRoot(mgpp_element);
     190    } else {
     191        // If the MGPP indexes element is empty (ie was created by CollectionConfiguration), generate new MGPP index from the existing index
     192       
     193        ArrayList sources_list = new ArrayList();
     194        // We first use details from the default index if any
     195        if(default_index != null) {
     196        ArrayList sources = default_index.getSources();
     197        sources_list.addAll(sources);
     198        }
     199        int size = getSize();
     200        for(int i = 0; i < size; i++) {
     201        Index index = (Index) getElementAt(i);
     202        ArrayList sources = index.getSources();
     203        sources.removeAll(sources_list);
     204        sources_list.addAll(sources);
     205        index = null;
     206        }
     207        // Replace mg element with mgpp element
     208        setRoot(mgpp_element);
     209       
     210        // We now have a list of sources, so create new indexes based on these
     211        int sources_list_size = sources_list.size();
     212        for(int j = 0; j < sources_list_size; j++) {
     213        Object source_object = sources_list.get(j);
     214        String source_str = null;
     215        if(source_object instanceof MetadataElement) {
     216            source_str = ((MetadataElement) source_object).getFullName();
     217        }
     218        else {
     219            source_str = source_object.toString();
     220        }
     221        ArrayList new_sources = new ArrayList();
     222        new_sources.add(source_object);
     223        source_object = null;
     224        Index new_index = new Index(new_sources);
     225        // Try to retrieve existing metadatum
     226        source_str = new_index.getID();
     227        CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + source_str, false);
     228        // If no metadata was found, add new pseudo metadata using the id
     229        if(metadatum == null) {
     230            metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source_str);
     231            metadatum.setAssigned(true);
     232            metadatum.setValue(source_str);
     233        }
     234        // If it was found, ensure it is assigned
     235        else {
     236            metadatum.setAssigned(true);
     237        }
     238        source_str = null;
     239        addIndex(new_index, metadatum);
     240        metadatum = null;
     241        new_index = null;
     242        new_sources = null;
     243        source_str = null;
     244        }
     245       
     246    }
     247
     248    // Unassign MG element
     249    mg_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
     250    mg_element = null;
     251   
     252    }
     253   
    139254    public Control getControls() {
    140     if(controls == null) {
    141         // Build controls
     255    if (controls == null) {
    142256        controls = new IndexControl();
    143257    }
    144258    return controls;
    145     }
    146 
    147     /** Method to get the default index.
    148      * @return The default <strong>Index</strong>.
    149      */
    150     public Index getDefault() {
    151     if(default_index != null && default_index.isAssigned()) {
    152         return default_index;
    153     }
    154     else {
    155         return null;
    156     }
    157259    }
    158260
     
    187289    }
    188290
    189     public Level getLevel(String name) {
    190     int levels_model_size = levels_model.getSize();
    191     for(int i = 0; i < levels_model_size; i++) {
    192         Level level = (Level) levels_model.getElementAt(i);
    193         if(level.getLevel().equals(name)) {
    194         return level;
    195         }
    196     }
    197     return null;
    198     }
    199 
    200     public int getNumLevels() {
    201     return levels_model.getSize();
    202     }
     291
     292
     293    /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
     294     * @param mode the new mode as an int
     295     */
     296    public void modeChanged(int mode) {
     297
     298    }
     299
    203300    private void moveIndex(Index index, boolean move_up)
    204301    {
     
    235332
    236333
    237     private void moveLevel(Level level, boolean move_up) {
    238     // Determine the leveles current position
    239     int position = levels_model.indexOf(level);
    240     // Determine if it can be moved, ie if its not already at the top trying to move up, or at the bottom trying to move down.
    241     if(position == -1) {
    242         return;
    243     }
    244     if(position == 0 && move_up) {
    245         return;
    246     }
    247     if(position == (levels_model.getSize()) - 1 && !move_up) {
    248         return;
    249     }
    250     // Ok, move up
    251     if(move_up) {
    252         position--;
    253         levels_model.remove(level);
    254         levels_model.add(position, level);
    255     }
    256     // Or move down
    257     else {
    258         position++;
    259         levels_model.remove(level);
    260         levels_model.add(position, level);
    261     }
    262     // Schedule the collection for saving
    263     Gatherer.c_man.configurationChanged();
    264     }
    265    
     334
    266335    /** Method to remove a certain index.
    267336     * @param index the Index to remove.
     
    293362    }
    294363
    295     private void removeLevel(Level level) {
    296     if(level != null) {
    297         // Remove any current metadata from this level
    298         CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + level.getLevel());
    299         // Remove the level
    300         levels_model.remove(level);
    301         Gatherer.c_man.configurationChanged();
    302     }
    303     }
    304364
    305365    /* replace an index in the list. new index may have the same sources but a
     
    329389    Gatherer.c_man.configurationChanged();
    330390    }
     391
    331392
    332393    /** Method to set the default index.
     
    362423    }
    363424
    364     /** This method is reponsible for changing the underlying Index commands from MG to MGPP and back again. This turns out to be easyish for MG->MGPP and very hard for the reverse. For the former we remove the level fragment and make sure the same levels are set, then we produce a list of the sources involved, breaking down comma seperated lists and making sure each item it unique. Changing back the other way turns out to be impossible, so we don't (beyond generating document:text, section:text and paragraph:text if text is an index and the respective levels are present). In either case we start by creating a comment containing the old index information.
    365      * @param  state true to enable MGPP indexes, false to use standard MG style ones
    366      */
    367     public void setMGPPEnabled(boolean state) {
    368     if(state == root.getAttribute(CollectionConfiguration.MGPP_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR)) {
    369         // we are not changing state
    370         return;
    371        
    372     }
    373     // change MG -> MGPP
    374     if(state) {
    375         Element mg_element = root;
    376         // Retrieve and assign the MGPP indexes element.
    377         Element mgpp_element = CollectionDesignManager.collect_config.getMGPPIndexes();
    378         mgpp_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
    379         levels_model.root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
    380         // If the MGPP indexes element is empty (ie was created by CollectionConfiguration), generate new MGPP index from the existing index
    381         NodeList indexes = mgpp_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
    382         if(indexes.getLength() == 0) {
    383         ArrayList levels_list = new ArrayList();
    384         ArrayList sources_list = new ArrayList();
    385         // We first use details from the default index if any
    386         if(default_index != null) {
    387             int level_int = default_index.getLevel();
    388             if(0 <= level_int && level_int < 3) {
    389             String level = Index.LEVEL[level_int];
    390             levels_list.add(level);
    391             level = null;
    392             }
    393             ArrayList sources = default_index.getSources();
    394             sources_list.addAll(sources);
    395         }
    396         int size = getSize();
    397         for(int i = 0; i < size; i++) {
    398             Index index = (Index) getElementAt(i);
    399             int level_int = index.getLevel();
    400             if(0 <= level_int && level_int < 3) {
    401             String level = Index.LEVEL[level_int];
    402             if(!levels_list.contains(level)) {
    403                 levels_list.add(level);
    404             }
    405             level = null;
    406             }
    407             ArrayList sources = index.getSources();
    408             sources.removeAll(sources_list);
    409             sources_list.addAll(sources);
    410             index = null;
    411         }
    412         // Replace mg element with mgpp element
    413         setRoot(mgpp_element);
    414        
    415         // We now have a list of sources and a list of levels, so create new indexes and levels based on these
    416         int sources_list_size = sources_list.size();
    417         for(int j = 0; j < sources_list_size; j++) {
    418             Object source_object = sources_list.get(j);
    419             String source_str = null;
    420             if(source_object instanceof MetadataElement) {
    421             source_str = ((MetadataElement) source_object).getFullName();
    422             }
    423             else {
    424             source_str = source_object.toString();
    425             }
    426             ArrayList new_sources = new ArrayList();
    427             new_sources.add(source_object);
    428             source_object = null;
    429             Index new_index = new Index(new_sources);
    430             // Try to retrieve existing metadatum
    431             source_str = new_index.getID();
    432             CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + source_str, false);
    433             // If no metadata was found, add new pseudo metadata using the id
    434             if(metadatum == null) {
    435             metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source_str);
    436             metadatum.setAssigned(true);
    437             metadatum.setValue(source_str);
    438             }
    439             // If it was found, ensure it is assigned
    440             else {
    441             metadatum.setAssigned(true);
    442             }
    443             source_str = null;
    444             addIndex(new_index, metadatum);
    445             metadatum = null;
    446             new_index = null;
    447             new_sources = null;
    448             source_str = null;
    449         }
    450         int levels_list_size = levels_list.size();
    451         for(int k = 0; k < levels_list_size; k++) {
    452             String level_name = (String)levels_list.get(k);
    453             Level new_level = new Level(level_name);
    454             if(!levels_model.contains(new_level)) {
    455             CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + level_name, false);
    456             // If no metadata was found, add new pseudo metadata using the id
    457             if(metadatum == null) {
    458                 metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + level_name);
    459                 metadatum.setAssigned(true);
    460                 metadatum.setValue(level_name);
    461             }
    462             addLevel(new_level, metadatum);
    463             }
    464             new_level = null;
    465            
    466         }
    467         }
    468         else {
    469         // we already have mgpp indexes assigned
    470         // Replace mg element with mgpp element
    471         setRoot(mgpp_element);
    472         }
    473         // Unassign MG element and default index
    474         mg_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
    475         mg_element = null;
    476     }
    477     // change MGPP -> MG
    478     else {
    479         Element mgpp_element = root;
    480         // Retrieve and assign MG element and default index element
    481         Element mg_element = CollectionDesignManager.collect_config.getMGIndexes();
    482         mg_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
    483         // If mg element has no indexes, and the current mgpp index include a text one, then generate text indexes for each of the registered levels.
    484         NodeList indexes = mg_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
    485         if(indexes.getLength() == 0) {
    486         Index index = getIndex(CollectionConfiguration.TEXT_STR);
    487         if(index != null) {
    488             // Replace mgpp element with mg element
    489             setRoot(mg_element);
    490             int level_size = levels_model.getSize();
    491             for(int i = 0; i < level_size; i++) {
    492             Level level = (Level) levels_model.getElementAt(i);
    493             Index new_index = new Index(level.getLevel(), index.getSources());
    494             // Try to retrieve existing metadatum
    495             String source_str = new_index.getID();
    496             CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + source_str, false);
    497             // If no metadata was found, add new pseudo metadata using the id
    498             if(metadatum == null) {
    499                 metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source_str);
    500                 metadatum.setAssigned(true);
    501                 metadatum.setValue(source_str);
    502             }
    503             // If it was found, ensure it is assigned
    504             else {
    505                 metadatum.setAssigned(true);
    506             }
    507             source_str = null;
    508             addIndex(new_index, metadatum);
    509             new_index = null;
    510             level = null;
    511             }
    512         }
    513         }
    514         else {
    515         // Replace mgpp element with mg element
    516         setRoot(mg_element);
    517         }
    518         // Unassign mgpp element and levels
    519         mgpp_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
    520         levels_model.root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
    521     }
    522     // its really hard to transfer defaults between mg and mgpp. so we'll just assign the first one to be the default.
    523     Index first_index = (Index) getElementAt(0);
    524     setDefault(first_index);
    525     first_index = null;
    526    
    527    
    528     }
    529    
    530 
    531     /** This class creates a set of controls for editing the indexes. */
     425
    532426    private class IndexControl
    533427    extends JPanel
    534428    implements Control {
    535429
    536     //  private JTextArea instruction_textarea;
    537 
    538430    private JList index_list;
    539 
    540431    private JButton move_down_button;
    541432    private JButton move_up_button;
    542433    private JButton set_default_button;
    543434
    544     private JTextField name_textfield ;
     435    private JButton new_button;
     436    private JButton edit_button;
     437    private JButton remove_button;
     438
     439    public IndexControl() {
     440        super();
     441
     442        // Creation
     443        JPanel assigned_indexes_pane = new JPanel();
     444       
     445        JLabel index_label = new JLabel();
     446        Dictionary.registerText(index_label, "CDM.IndexManager.Indexes");
     447        index_list = new JList(index_model);
     448        index_list.setCellRenderer(new IndexListRenderer());
     449        index_list.setVisibleRowCount(6);
     450        index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     451
     452        JPanel movement_pane = new JPanel();
     453        move_up_button = new GLIButton("", JarTools.getImage("arrow-up.gif"));
     454        move_up_button.setEnabled(false);
     455        move_up_button.setMnemonic(KeyEvent.VK_U);
     456        Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
     457
     458        move_down_button = new GLIButton("", JarTools.getImage("arrow-down.gif"));
     459        move_down_button.setEnabled(false);
     460        move_down_button.setMnemonic(KeyEvent.VK_D);
     461        Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
     462       
     463        set_default_button = new GLIButton();
     464        set_default_button.setEnabled(false);
     465        set_default_button.setMnemonic(KeyEvent.VK_S);
     466        Dictionary.registerBoth(set_default_button, "CDM.IndexManager.Set_Default", "CDM.IndexManager.Set_Default_Tooltip");
     467
     468        JPanel button_pane = new JPanel();
     469        new_button = new GLIButton();
     470        new_button.setEnabled(true);
     471        new_button.setMnemonic(KeyEvent.VK_A);
     472        Dictionary.registerBoth(new_button, "CDM.IndexManager.New_Index", "CDM.IndexManager.New_Index_Tooltip");
     473        edit_button = new GLIButton();
     474        edit_button.setEnabled(false);
     475        edit_button.setMnemonic(KeyEvent.VK_A);
     476        Dictionary.registerBoth(edit_button, "CDM.IndexManager.Edit_Index", "CDM.IndexManager.Edit_Index_Tooltip");
     477        remove_button = new GLIButton();
     478        remove_button.setEnabled(false);
     479        remove_button.setMnemonic(KeyEvent.VK_R);
     480        Dictionary.registerBoth(remove_button, "CDM.IndexManager.Remove_Index", "CDM.IndexManager.Remove_Index_Tooltip");
     481     
     482        // Listeners
     483        new_button.addActionListener(new NewIndexListener());
     484        edit_button.addActionListener(new EditIndexListener());
     485        remove_button.addActionListener(new RemoveIndexListener());
     486
     487        index_list.addListSelectionListener(new IndexListListener());
     488
     489        move_down_button.addActionListener(new MoveListener(false));
     490        move_up_button.addActionListener(new MoveListener(true));
     491
     492        set_default_button.addActionListener(new SetDefaultListener());
     493        // Layout
     494        movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
     495        movement_pane.setLayout(new GridLayout(3,1));
     496        movement_pane.add(move_up_button);
     497        movement_pane.add(move_down_button);
     498        movement_pane.add(set_default_button);
     499
     500        assigned_indexes_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     501        assigned_indexes_pane.setLayout(new BorderLayout());
     502        assigned_indexes_pane.add(index_label, BorderLayout.NORTH);
     503        assigned_indexes_pane.add(new JScrollPane(index_list), BorderLayout.CENTER);
     504        assigned_indexes_pane.add(movement_pane, BorderLayout.EAST);
     505
     506        button_pane.setLayout(new GridLayout(1,3,5,0));
     507        button_pane.add(new_button);
     508        button_pane.add(edit_button);
     509        button_pane.add(remove_button);
     510
     511        setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
     512        setLayout(new BorderLayout());
     513        add(assigned_indexes_pane, BorderLayout.CENTER);
     514        add(button_pane, BorderLayout.SOUTH);
     515       
     516    }
     517    public void loseFocus() {}
     518    public void gainFocus() {}
     519    public void destroy() {}
     520   
     521    private class IndexListListener
     522        implements ListSelectionListener {
     523       
     524        /** This method is called whenever the source list selection changes. When it does we need to fill in the various parts of the list description panel
     525         * @param event A <strong>ListSelectionEvent</strong> containing further information about the list selection.
     526         */
     527        public void valueChanged(ListSelectionEvent event)
     528        {
     529        if (event.getValueIsAdjusting()) {
     530            return;
     531        }
     532       
     533        Object value = index_list.getSelectedValue();
     534        if (value == null) {
     535            move_down_button.setEnabled(false);
     536            move_up_button.setEnabled(false);
     537            remove_button.setEnabled(false);
     538            edit_button.setEnabled(false);
     539            set_default_button.setEnabled(false);
     540            return;
     541        }
     542
     543        // Enable the buttons appropriately
     544        remove_button.setEnabled(true);
     545        edit_button.setEnabled(true);
     546        set_default_button.setEnabled(default_index == null || !default_index.equals(value));
     547        int i = index_list.getSelectedIndex();
     548        int size = index_list.getModel().getSize();
     549        move_up_button.setEnabled((i>0));
     550        move_down_button.setEnabled((i<size-1));
     551        }
     552    }
     553
     554    private class IndexListRenderer
     555        extends DefaultListCellRenderer {
     556
     557        /** Return a component that has been configured to display the specified value. */
     558        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
     559        JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     560        if(default_index != null && default_index.equals(value)) {
     561            component.setText(component.getText() + " " + Dictionary.get("CDM.IndexManager.Default_Index_Indicator"));
     562        }
     563        return component;
     564        }
     565
     566    }
     567
     568    private class NewIndexListener
     569        implements ActionListener {
     570
     571        public void actionPerformed(ActionEvent event) {
     572        NewIndexPrompt nip = new NewIndexPrompt(build_type, null);
     573        nip.destroy();
     574        }
     575    }
     576   
     577    private class EditIndexListener
     578        implements ActionListener {
     579
     580        public void actionPerformed(ActionEvent event) {
     581        Index index = (Index) index_list.getSelectedValue();
     582        NewIndexPrompt nip = new NewIndexPrompt(build_type, index);
     583        nip.destroy();
     584        }
     585    }
     586
     587    private class RemoveIndexListener
     588        implements ActionListener {
     589       
     590        public void actionPerformed(ActionEvent event) {
     591       
     592        int i = index_list.getSelectedIndex();
     593        if (i != -1) {
     594            removeIndex((Index) index_list.getSelectedValue());
     595        }
     596        int size = index_list.getModel().getSize();
     597        if (i == size) {
     598            i--;
     599        }
     600        index_list.setSelectedIndex(i);
     601        // This will produce an event on the list, updating the other buttons
     602        if (size == 0) {
     603            // We have removed the last index, should be able to add what's filled in currently, if valid
     604            //   validateAddButton();
     605        }
     606        }
     607    }
     608
     609    private class MoveListener
     610        implements ActionListener {
     611
     612        private boolean move_up;
     613
     614        public MoveListener(boolean move_up) {
     615        this.move_up = move_up;
     616        }
     617
     618        public void actionPerformed(ActionEvent event) {
     619        // Retrieve the selected index
     620        Index index = (Index) index_list.getSelectedValue();
     621        if(index != null) {
     622            moveIndex(index, move_up);
     623            // Ensure the index that moved is still selected
     624            index_list.setSelectedValue(index, true);
     625            index = null;
     626        }
     627        }
     628    }
     629
     630    private class SetDefaultListener
     631        implements ActionListener {
     632
     633        public void actionPerformed(ActionEvent event) {
     634        Index index = (Index) index_list.getSelectedValue();
     635        if(index != null) {
     636            setDefault(index);
     637            // This should cause a repaint of just the desired row
     638            index_list.setSelectedValue(index, true);
     639        }
     640        set_default_button.setEnabled(false);
     641        }
     642    }
     643
     644   
     645
     646    private class NewIndexPrompt
     647    extends ModalDialog {
     648
     649    NewIndexPrompt new_index_prompt = null;
     650   
    545651    private CheckList source_list;
    546652    // mg uses a level box
     
    550656
    551657    private JButton add_button;
     658    private JButton replace_button;
    552659    private JButton add_all_button;
    553     private JButton remove_button;
    554     private JButton replace_button;
    555 
    556     // soem panels that we need to manipulate later on
     660    private JButton cancel_button;
     661
     662    // some panels that we need to manipulate later on
    557663    private JPanel boxes_pane;
    558664    private JPanel labels_pane;
    559665    private JLabel level_label;
    560666    private JPanel allfields_pane;
    561    
    562     // we add in a tabbed pane for mgpp mode
    563     private JTabbedPane tabbed_pane;
    564     // the main index set up pane
    565     private JPanel main_index_pane;
    566 
    567     // for the levels tab in mgpp mode
    568     private MGPPLevelsPanel mgpplevels_pane;
    569667
    570668    private boolean mgpp_enabled = false;
    571     /** Constructor.
    572      * @see org.greenstone.gatherer.Configuration
    573      * @see org.greenstone.gatherer.Gatherer
    574      * @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.AddListener
    575      * @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.NameListener
    576      * @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.RemoveListener
    577      * @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.SetDefaultListener
    578      * @see org.greenstone.gatherer.collection.CollectionManager
    579      */
    580     public IndexControl() {
    581         super();
    582 
     669    private boolean editing = false;
     670   
     671    public NewIndexPrompt(String build_type, Index existing_index) {
     672        super(Gatherer.g_man, true);
     673        new_index_prompt = this;
     674
     675        setModal(true);
     676        setSize(PROMPT_SIZE);
     677        if (existing_index != null) {
     678        setTitle (Dictionary.get("CDM.IndexManager.Edit_Index"));
     679        editing = true;
     680        } else {
     681        setTitle(Dictionary.get("CDM.IndexManager.New_Index"));
     682        }
     683       
     684        if (build_type.equals(BuildTypeManager.BUILD_TYPE_MGPP) || build_type.equals(BuildTypeManager.BUILD_TYPE_LUCENE)) {
     685        mgpp_enabled = true;
     686        }
     687        JPanel content_pane = (JPanel)this.getContentPane();
    583688        ArrayList new_data = new ArrayList();
    584689        new_data.add(CollectionConfiguration.TEXT_STR);
    585690        new_data.addAll(MetadataSetManager.getEveryMetadataSetElement());
    586        
    587         // Creation
    588         JPanel header_pane = new DesignPaneHeader("CDM.GUI.Indexes", "searchindexes");     
    589         JPanel assigned_indexes_pane = new JPanel();
    590         JLabel index_label = new JLabel();
    591         Dictionary.registerText(index_label, "CDM.IndexManager.Indexes");
    592         index_list = new JList(model);
    593         index_list.setCellRenderer(new IndexListRenderer());
    594         index_list.setVisibleRowCount(2);
    595         index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    596        
    597        
    598         JPanel movement_pane = new JPanel();
    599         move_up_button = new GLIButton("", JarTools.getImage("arrow-up.gif"));
    600         move_up_button.setEnabled(false);
    601         move_up_button.setMnemonic(KeyEvent.VK_U);
    602         Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
    603 
    604         move_down_button = new GLIButton("", JarTools.getImage("arrow-down.gif"));
    605         move_down_button.setEnabled(false);
    606         move_down_button.setMnemonic(KeyEvent.VK_D);
    607         Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
    608        
    609         set_default_button = new GLIButton();
    610         set_default_button.setEnabled(false);
    611         set_default_button.setMnemonic(KeyEvent.VK_S);
    612         Dictionary.registerBoth(set_default_button, "CDM.IndexManager.Set_Default", "CDM.IndexManager.Set_Default_Tooltip");
    613 
    614         JPanel new_index_pane = new JPanel();
     691
    615692        JPanel details_pane = new JPanel();
    616693        labels_pane = new JPanel();
    617694        boxes_pane = new JPanel();
    618         main_index_pane = new JPanel();
    619 
    620         JLabel name_label = new JLabel();
    621         Dictionary.registerText(name_label, "CDM.IndexManager.Index_Name");
    622         name_textfield = new JTextField();
    623         name_textfield.setPreferredSize(FIELD_SIZE);
    624         Dictionary.registerTooltip(name_textfield, "CDM.IndexManager.Index_Name_Tooltip");
     695
     696        JPanel main_index_pane = new JPanel();
    625697
    626698        JLabel source_label = new JLabel();
     
    629701        source_list.setListData(new_data);
    630702        Dictionary.registerTooltip(source_list, "CDM.IndexManager.Source_Tooltip");
    631 
    632         level_label = new JLabel();
    633         Dictionary.registerText(level_label, "CDM.IndexManager.Level");
    634         level_combobox = new JComboBox();
    635         level_combobox.setPreferredSize(FIELD_SIZE);
    636         level_combobox.addItem(CollectionConfiguration.DOCUMENT_STR);//Dictionary.get("CDM.IndexManager.Document"));
    637         level_combobox.addItem(CollectionConfiguration.PARAGRAPH_STR);//Dictionary.get("CDM.IndexManager.Paragraph"));
    638         level_combobox.addItem(CollectionConfiguration.SECTION_STR);//Dictionary.get("CDM.IndexManager.Section"));
    639         level_combobox.setEditable(false);
    640         Dictionary.registerTooltip(level_combobox, "CDM.IndexManager.Level_Tooltip");
     703        source_list.addListSelectionListener(new SourceListListener());
    641704
    642705        JPanel button_pane = new JPanel();
    643         add_button = new GLIButton();
    644         add_button.setEnabled(false);
    645         add_button.setMnemonic(KeyEvent.VK_A);
    646         Dictionary.registerBoth(add_button, "CDM.IndexManager.Add_Index", "CDM.IndexManager.Add_Index_Tooltip");
    647 
    648         add_all_button = new GLIButton();
    649         add_all_button.setEnabled(true);
    650         add_all_button.setMnemonic(KeyEvent.VK_L);
    651         Dictionary.registerBoth(add_all_button, "CDM.IndexManager.MGPP.Add_All_Metadata", "CDM.IndexManager.MGPP.Add_All_Metadata_Tooltip");
    652 
    653         remove_button = new GLIButton();
    654         remove_button.setEnabled(false);
    655         remove_button.setMnemonic(KeyEvent.VK_R);
    656         Dictionary.registerBoth(remove_button, "CDM.IndexManager.Remove_Index", "CDM.IndexManager.Remove_Index_Tooltip");
    657         replace_button = new GLIButton();
    658         replace_button.setEnabled(false);
    659         replace_button.setMnemonic(KeyEvent.VK_P);
    660         Dictionary.registerBoth(replace_button, "CDM.IndexManager.MGPP.Replace_Index", "CDM.IndexManager.MGPP.Replace_Index_Tooltip");
    661 
    662         allfields_pane = new JPanel();
    663         allfields_box = new JCheckBox();
    664         JLabel allfields_label = new JLabel();
    665         Dictionary.registerText(allfields_label, "CDM.IndexManager.Allfields_Index");
    666         allfields_pane.setLayout(new BorderLayout());
    667         allfields_pane.add(allfields_box, BorderLayout.WEST);
    668         allfields_pane.add(allfields_label, BorderLayout.CENTER);
    669        
    670         // Listeners
    671         add_button.addActionListener(new AddListener());
    672         add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    673         add_all_button.addActionListener(new AddAllActionListener());
    674         add_all_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    675         remove_button.addActionListener(new RemoveListener());
    676         remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    677         replace_button.addActionListener(new ReplaceListener());
    678         replace_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    679         move_down_button.addActionListener(new MoveListener(false));
    680         move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    681         move_up_button.addActionListener(new MoveListener(true));
    682         move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    683         set_default_button.addActionListener(new SetDefaultListener());
    684         set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
    685 
    686         name_textfield.getDocument().addDocumentListener(new NameListener());
    687         level_combobox.addItemListener(new LevelListener());
    688         index_list.addListSelectionListener(new IndexListListener());
    689         source_list.addListSelectionListener(new SourceListListener());
    690         allfields_box.addItemListener(new AllfieldsCheckBoxListener());
     706        if (existing_index != null) {
     707        button_pane.setLayout(new GridLayout(1,2,5,0));
     708        replace_button = new GLIButton();
     709        replace_button.setEnabled(false);
     710        Dictionary.registerBoth(replace_button, "CDM.IndexManager.Replace_Index", "CDM.IndexManager.Replace_Index_Tooltip");
     711        button_pane.add(replace_button);
     712        replace_button.addActionListener(new ReplaceIndexListener());
     713        } else {
     714        button_pane.setLayout(new GridLayout(1,3,5,0));
     715        add_button = new GLIButton();
     716        add_button.setEnabled(false);
     717        add_button.setMnemonic(KeyEvent.VK_A);
     718        Dictionary.registerBoth(add_button, "CDM.IndexManager.Add_Index", "CDM.IndexManager.Add_Index_Tooltip");
     719        add_button.addActionListener(new AddIndexListener());
     720
     721       
     722        add_all_button = new GLIButton();
     723        add_all_button.setEnabled(true);
     724        add_all_button.setMnemonic(KeyEvent.VK_L);
     725        Dictionary.registerBoth(add_all_button, "CDM.IndexManager.Add_All", "CDM.IndexManager.Add_All_Tooltip");
     726        add_all_button.addActionListener(new AddAllIndexActionListener());     
     727        button_pane.add(add_button);
     728        button_pane.add(add_all_button);
     729
     730        }
     731        cancel_button = new GLIButton();
     732        cancel_button.setEnabled(true);
     733        Dictionary.registerBoth(cancel_button, "General.Cancel", "General.Cancel");
     734        cancel_button.addActionListener(new ActionListener() {
     735        public void actionPerformed(ActionEvent event) {
     736            new_index_prompt.dispose();
     737        }
     738        });
     739        button_pane.add(cancel_button);
    691740
    692741        // Layout
    693 
    694         movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
    695         movement_pane.setLayout(new GridLayout(3,1));
    696         movement_pane.add(move_up_button);
    697         movement_pane.add(move_down_button);
    698         movement_pane.add(set_default_button);
    699 
    700         assigned_indexes_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    701         assigned_indexes_pane.setLayout(new BorderLayout());
    702         assigned_indexes_pane.add(index_label, BorderLayout.NORTH);
    703         assigned_indexes_pane.add(new JScrollPane(index_list), BorderLayout.CENTER);
    704         assigned_indexes_pane.add(movement_pane, BorderLayout.EAST);
    705 
    706742        labels_pane.setLayout(new BorderLayout());
    707743        labels_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
    708         labels_pane.add(name_label, BorderLayout.NORTH);
    709744        labels_pane.add(source_label, BorderLayout.CENTER);
    710         labels_pane.add(level_label, BorderLayout.SOUTH);
    711745       
    712746        boxes_pane.setLayout(new BorderLayout());
    713         boxes_pane.add(name_textfield, BorderLayout.NORTH);
    714747        boxes_pane.add(new JScrollPane(source_list), BorderLayout.CENTER);
    715         boxes_pane.add(level_combobox, BorderLayout.SOUTH);
    716748       
    717749        details_pane.setLayout(new BorderLayout());
     
    719751        details_pane.add(boxes_pane, BorderLayout.CENTER);
    720752
    721         button_pane.setLayout(new GridLayout(2,2,5,0));
    722         button_pane.add(add_button);
    723         button_pane.add(add_all_button);
    724         button_pane.add(replace_button);
    725         button_pane.add(remove_button);
    726 
    727         new_index_pane.setLayout(new BorderLayout());
    728         new_index_pane.add(details_pane, BorderLayout.CENTER);
    729         new_index_pane.add(button_pane, BorderLayout.SOUTH);
    730 
    731         main_index_pane.setLayout(new BorderLayout());
    732         main_index_pane.add(assigned_indexes_pane, BorderLayout.NORTH);
    733         main_index_pane.add(new_index_pane, BorderLayout.CENTER);
    734 
    735         setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
    736         setLayout(new BorderLayout());
    737         add(header_pane, BorderLayout.NORTH);
    738         add(main_index_pane, BorderLayout.CENTER);
    739 
    740         // for later, if we go to MGPP mode
    741         tabbed_pane = new JTabbedPane();
    742     }
    743 
    744    
    745     /* Destructor, removes persistant listeners from the Dictionary.
     753
     754        // do type specific stuff
     755        if (!mgpp_enabled) {
     756
     757        level_label = new JLabel();
     758        Dictionary.registerText(level_label, "CDM.IndexManager.Level");
     759        level_combobox = new JComboBox();
     760        level_combobox.setPreferredSize(FIELD_SIZE);
     761        level_combobox.addItem(CollectionConfiguration.DOCUMENT_STR);//Dictionary.get("CDM.IndexManager.Document"));
     762        level_combobox.addItem(CollectionConfiguration.PARAGRAPH_STR);//Dictionary.get("CDM.IndexManager.Paragraph"));
     763        level_combobox.addItem(CollectionConfiguration.SECTION_STR);//Dictionary.get("CDM.IndexManager.Section"));
     764        level_combobox.setEditable(false);
     765        Dictionary.registerTooltip(level_combobox, "CDM.IndexManager.Level_Tooltip");
     766        labels_pane.add(level_label, BorderLayout.SOUTH);
     767        boxes_pane.add(level_combobox, BorderLayout.SOUTH);
     768
     769        } else {
     770        allfields_pane = new JPanel();
     771        allfields_box = new JCheckBox();
     772        JLabel allfields_label = new JLabel();
     773        Dictionary.registerText(allfields_label, "CDM.IndexManager.Allfields_Index");
     774        allfields_pane.setLayout(new BorderLayout());
     775        allfields_pane.add(allfields_box, BorderLayout.WEST);
     776        allfields_pane.add(allfields_label, BorderLayout.CENTER);
     777       
     778
     779        }
     780        // if we are editing, fill in the controls
     781        if (existing_index !=null) {
     782        ArrayList sources = existing_index.getSources();
     783        if (mgpp_enabled && sources.get(0).equals(ALLFIELDS)) {
     784            source_list.setEnabled(false);
     785            allfields_box.setSelected(true);
     786        } else {
     787            source_list.setTickedObjects(sources.toArray());
     788            source_list.setEnabled(true);
     789        }
     790        if (!mgpp_enabled) {
     791            level_combobox.setSelectedIndex(existing_index.getLevel());
     792        }
     793       
     794        }
     795        content_pane.setLayout(new BorderLayout());
     796        content_pane.add(details_pane, BorderLayout.CENTER);
     797        content_pane.add(button_pane, BorderLayout.SOUTH);
     798       
     799        // Display on screen.
     800        Dimension screen_size = Configuration.screen_size;
     801        setLocation((screen_size.width - PROMPT_SIZE.width) / 2, (screen_size.height - PROMPT_SIZE.height) / 2);
     802        screen_size = null;
     803        setVisible(true);
     804       
     805    }
     806
     807    /** Method which actually forces the dialog to be shown on screen.
     808     * @return <i>true</i> if the user completed configuration and pressed ok, <i>false</i> otherwise.
    746809     */
     810    public boolean display() {
     811        setVisible(true);
     812        return true;
     813        //    return success;
     814    }
     815   
    747816    public void destroy() {
    748817    }
    749818
    750     public void gainFocus() {
    751         boolean old_mgpp_enabled = mgpp_enabled;
    752         mgpp_enabled = CollectionDesignManager.searchtype_manager.isSearchTypeEnabled();
    753         boolean changed_state = (old_mgpp_enabled != mgpp_enabled);
    754         if (changed_state) {
    755         // reset the underlying indexes and levels elements
    756         setMGPPEnabled(mgpp_enabled);
    757         }
    758         /* reset the source list - may have built between then and now */
    759         ArrayList new_data = new ArrayList();
    760         new_data.add(CollectionConfiguration.TEXT_STR);
    761         new_data.addAll(MetadataSetManager.getEveryMetadataSetElement());
    762         source_list.setListData(new_data);
    763         new_data = null;
    764        
    765         if(mgpp_enabled) {
    766         if (changed_state) {
    767             // switch the variable bits
    768             boxes_pane.remove(level_combobox);
    769             labels_pane.remove(level_label);
    770             boxes_pane.add(allfields_pane, BorderLayout.SOUTH);
    771             //put back the tabbed pane
    772             remove(main_index_pane);
    773             add(tabbed_pane, BorderLayout.CENTER);
    774             tabbed_pane.insertTab(Dictionary.get("CDM.IndexManager.MGPP.Indexes"), null, main_index_pane, null, 0);
    775             if (mgpplevels_pane == null) {
    776             mgpplevels_pane = new MGPPLevelsPanel();
    777             tabbed_pane.insertTab(Dictionary.get("CDM.IndexManager.MGPP.Levels"), null, mgpplevels_pane, null, 1);
    778             }
    779             index_list.setSelectedIndex(0);
    780            
    781         }
    782         }
    783         else {
    784         if (changed_state) {
    785             boxes_pane.remove(allfields_pane);
    786             boxes_pane.add(level_combobox, BorderLayout.SOUTH);
    787             labels_pane.add(level_label, BorderLayout.SOUTH);
    788             remove(tabbed_pane);
    789             tabbed_pane.remove(0);
    790             add(main_index_pane, BorderLayout.CENTER);
    791             source_list.setEnabled(true); // in case it had been disabled
    792             allfields_box.setSelected(false);
    793             index_list.setSelectedIndex(0);
    794            
    795         }
    796         }
    797         updateControlsWithSelectedIndex();
    798        
    799     }
    800 
    801     public void loseFocus() {
    802     }
    803    
    804     private void updateControlsWithSelectedIndex() {
    805        
    806         Index selected_index = (Index)index_list.getSelectedValue();
    807         if (selected_index == null) {
    808         return;
    809         }
    810         String id = selected_index.getID();
    811         if (id == null || id.equals("")) {
    812         return;
    813         }
    814         String name = CollectionDesignManager.collectionmeta_manager.getMetadatum("." + id).getValue(true);
    815         name_textfield.setText(name);
    816         if (!mgpp_enabled) {
    817         level_combobox.setSelectedIndex(selected_index.getLevel());
    818         }
    819         source_list.clearTicked();
    820         ArrayList sources = selected_index.getSources();
    821         if (mgpp_enabled && sources.get(0).equals(ALLFIELDS)) {
    822         source_list.setEnabled(false);
    823         allfields_box.setSelected(true);
    824         } else {
    825         source_list.setTickedObjects(sources.toArray());
    826         source_list.setEnabled(true);
    827         allfields_box.setSelected(false);
    828         }
    829     }
    830    
    831     private void validateAddButton() {
    832 
    833         String new_index_name = name_textfield.getText();
    834         // indexes must have a name
    835         if (new_index_name.length() == 0) {
    836         add_button.setEnabled(false);
    837         replace_button.setEnabled(false);
    838         return;
    839         }
    840        
    841         boolean add_enabled = false;
    842         boolean replace_enabled = false;
    843        
    844         Index index;
    845         ArrayList sources;
    846         if (mgpp_enabled && allfields_box.isSelected()) {
    847         sources = new ArrayList();
    848         sources.add(ALLFIELDS);
    849         index = new Index(sources);
    850 
    851         } else if (!source_list.isNothingTicked()) {
    852         Object object[] = source_list.getTicked().toArray();
    853         sources = new ArrayList();
    854         for(int i = 0; i < object.length; i++) {
    855             sources.add(object[i]);
    856         }
    857         object = null;
    858        
    859         if (mgpp_enabled) {
    860             index = new Index(sources);
    861         } else {
    862             index = new Index(level_combobox.getSelectedIndex(), sources);
    863         }
    864         } else {
    865         add_button.setEnabled(false);
    866         replace_button.setEnabled(false);
    867         return;
    868         }
    869         sources = null;
    870         if (model.contains(index)) {
    871         add_enabled = false;
    872         // may be able to replace if the index selected is the same but with a different name
    873         if (index_list.getSelectedIndex() != -1) {
    874             String id = index.getID();
    875             String selected_index_id = ((Index)index_list.getSelectedValue()).getID();
    876             if (id.equals(selected_index_id)) {
    877             // check the name
    878             String existing_index_name = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER+id).getValue(true);
    879             if (!existing_index_name.equals(new_index_name)) {
    880                 replace_enabled = true;
    881             }
    882             }
    883         }
    884         } else {
    885         add_enabled = true;
    886         if (index_list.getSelectedIndex() != -1) {
    887             // there is something selected, so we can replace
    888             replace_enabled = true;
    889         }
    890         }
    891        
    892         // We should now know the button state
    893         add_button.setEnabled(add_enabled);
    894         replace_button.setEnabled(replace_enabled);
    895     }
    896    
    897     private class AddListener
     819        private class AddIndexListener
    898820        implements ActionListener
    899821    {
    900822        public void actionPerformed(ActionEvent event)
    901823        {
    902         String name = name_textfield.getText();
    903         if (name.length() == 0) return;
    904824        Index index;
    905825        if (mgpp_enabled && allfields_box.isSelected()) {
     
    919839        }
    920840         
    921         // Before we add the index to the model, we have to add the collection metadata for this
     841        // Before we add the index to the model, we have to add a default collection metadata for this
    922842        CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + index.getID());
    923         metadatum.setValue(name);
     843        metadatum.setValue(index.getID());
    924844       
    925845        // Finally, add the index
    926846        addIndex(index, metadatum);
    927847        index_list.setSelectedValue(index, true);
    928         add_button.setEnabled(false);
    929        
     848        new_index_prompt.dispose();
    930849        }
    931850    }
     
    933852    /** add all sources as indexes. for MG, this adds them in one combined
    934853        index, for MGPP this adds them as individual indexes (fields) */
    935     private class AddAllActionListener
     854    private class AddAllIndexActionListener
    936855        implements ActionListener {
    937856
     
    940859        if (!mgpp_enabled) {
    941860            Index index = new Index(level_combobox.getSelectedIndex(), all_sources);
    942             if (!model.contains(index)) {
     861            if (!index_model.contains(index)) {
    943862            CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + index.getID());
    944863            metadatum.setValue("all fields"); // need a good name
     
    958877            new_sources.add(source);
    959878            Index index = new Index(new_sources);
    960             if(!model.contains(index)) {
     879            if(!index_model.contains(index)) {
    961880            // Determine the metadatum value
    962881            String name = source.toString();
     
    975894        }
    976895        new_sources = null;
    977         // Done. Disable add
    978         add_button.setEnabled(false);
    979         }
    980     }
    981 
    982     private class AllfieldsCheckBoxListener
    983         implements ItemListener
    984     {
    985         public void itemStateChanged(ItemEvent event) {
    986         if (event.getStateChange() == ItemEvent.SELECTED) {
    987             source_list.setEnabled(false);
    988         } else if (event.getStateChange() == ItemEvent.DESELECTED) {
    989             source_list.setEnabled(true);
    990         }
    991         validateAddButton();
    992         }
    993 
    994     }
    995     /** Listens for selections within the list on the IndexManager controls, and if a change is detected enables, or disables, controls appropriately. */
    996     private class IndexListListener
    997         implements ListSelectionListener
    998     {
    999         /** This method is called whenever the source list selection changes. When it does we need to fill in the various parts of the list description panel
    1000          * @param event A <strong>ListSelectionEvent</strong> containing further information about the list selection.
    1001          */
    1002         public void valueChanged(ListSelectionEvent event)
    1003         {
     896        new_index_prompt.dispose();
     897       
     898        }
     899    }
     900   
     901    private class SourceListListener
     902        implements ListSelectionListener {
     903       
     904        public void valueChanged(ListSelectionEvent event) {
    1004905        if (event.getValueIsAdjusting()) {
    1005906            return;
    1006907        }
    1007 
    1008         Object value = index_list.getSelectedValue();
    1009         if (value == null) {
    1010             move_down_button.setEnabled(false);
    1011             move_up_button.setEnabled(false);
    1012             remove_button.setEnabled(false);
    1013             replace_button.setEnabled(false);
    1014             set_default_button.setEnabled(false);
    1015             return;
    1016         }
    1017 
    1018         // Enable the buttons appropriately
    1019         remove_button.setEnabled(true);
    1020         set_default_button.setEnabled(default_index == null || !default_index.equals(value));
    1021         int i = index_list.getSelectedIndex();
    1022         int size = index_list.getModel().getSize();
    1023         move_up_button.setEnabled((i>0));
    1024         move_down_button.setEnabled((i<size-1));
    1025 
    1026         // Need to fill in the rest of the bits
    1027         updateControlsWithSelectedIndex();     
    1028         }
    1029     }
    1030 
    1031     private class IndexListRenderer
    1032         extends DefaultListCellRenderer {
    1033 
    1034         /** Return a component that has been configured to display the specified value. */
    1035         public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    1036         JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    1037         if(default_index != null && default_index.equals(value)) {
    1038             component.setText(component.getText() + " " + Dictionary.get("CDM.IndexManager.Default_Index_Indicator"));
    1039         }
    1040         return component;
    1041         }
    1042 
    1043     }
    1044 
    1045     private class LevelListener
    1046         implements ItemListener {
    1047         public void itemStateChanged(ItemEvent event) {
    1048         if(event.getStateChange() == ItemEvent.SELECTED) {
    1049             // just want to validate the add button
    1050             validateAddButton();
    1051 
    1052         }
    1053         }
    1054     }
    1055 
    1056     private class MoveListener
     908        boolean enabled = !source_list.isNothingTicked();
     909        if (editing) {
     910            replace_button.setEnabled(enabled);
     911        } else {
     912            add_button.setEnabled(enabled);
     913        }
     914       
     915        }
     916    }
     917   
     918
     919    private class ReplaceIndexListener
    1057920        implements ActionListener {
    1058 
    1059         private boolean move_up;
    1060 
    1061         public MoveListener(boolean move_up) {
    1062         this.move_up = move_up;
    1063         }
    1064 
     921       
    1065922        public void actionPerformed(ActionEvent event) {
    1066         // Retrieve the selected index
    1067         Index index = (Index) index_list.getSelectedValue();
    1068         if(index != null) {
    1069             moveIndex(index, move_up);
    1070             // Ensure the index that moved is still selected
    1071             index_list.setSelectedValue(index, true);
    1072             index = null;
    1073         }
    1074         }
    1075     }
    1076 
    1077 
    1078     /** Listens for key presses within the name field, and enabled or disables controls as appropriate. */
    1079     private class NameListener
    1080         implements DocumentListener
    1081     {
    1082         public void changedUpdate(DocumentEvent e)
    1083         {
    1084         validateAddButton();
    1085         }
    1086 
    1087         public void insertUpdate(DocumentEvent e)
    1088         {
    1089         validateAddButton();
    1090         }
    1091 
    1092         public void removeUpdate(DocumentEvent e)
    1093         {
    1094         validateAddButton();
    1095         }
    1096     }
    1097 
    1098 
    1099     private class RemoveListener
    1100         implements ActionListener
    1101     {
    1102         public void actionPerformed(ActionEvent event)
    1103         {
    1104         int i = index_list.getSelectedIndex();
    1105         if (i != -1) {
    1106             removeIndex((Index) index_list.getSelectedValue());
    1107         }
    1108         int size = index_list.getModel().getSize();
    1109         if (i == size) {
    1110             i--;
    1111         }
    1112         index_list.setSelectedIndex(i);
    1113         // This will produce an event on the list, updating the other buttons
    1114         if (size == 0) {
    1115             // We have removed the last index, should be able to add what's filled in currently, if valid
    1116             validateAddButton();
    1117         }
    1118         }
    1119     }
    1120 
    1121 
    1122     private class ReplaceListener
    1123         implements ActionListener
    1124     {
    1125         public void actionPerformed(ActionEvent event)
    1126         {
    1127         if (index_list.isSelectionEmpty()) {
    1128             // This should never happen, but just in case...
    1129             replace_button.setEnabled(false);
    1130             return;
    1131         }
    1132        
    1133         String name = name_textfield.getText();
    1134         if (name.length() == 0) {
    1135             // this also should never happen...
    1136             add_button.setEnabled(false);
    1137             replace_button.setEnabled(false);
    1138             return;
    1139         }
     923       
    1140924        ArrayList sources;
    1141925        Index index = null;
     
    1156940            // Create the new collection meta
    1157941            CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + index.getID());
    1158             metadatum.setValue(name);
     942            metadatum.setValue(index.getID());
    1159943           
    1160944            // replace the index
     
    1163947           
    1164948        }
    1165         add_button.setEnabled(false);
    1166         replace_button.setEnabled(false);
    1167         }
    1168     }
    1169 
    1170 
    1171     private class SetDefaultListener
    1172         implements ActionListener {
    1173 
    1174         public void actionPerformed(ActionEvent event) {
    1175         Index index = (Index) index_list.getSelectedValue();
    1176         if(index != null) {
    1177             setDefault(index);
    1178             // This should cause a repaint of just the desired row
    1179             index_list.setSelectedValue(index, true);
    1180         }
    1181         set_default_button.setEnabled(false);
    1182         }
    1183     }
    1184 
    1185 
    1186     private class SourceListListener
    1187         implements ListSelectionListener
    1188     {
    1189         public void valueChanged(ListSelectionEvent event)
    1190         {
    1191         validateAddButton();
    1192         }
    1193     }
    1194     }
    1195 
    1196     private class MGPPLevelsPanel
    1197     extends JPanel {
    1198 
    1199     private JList current_levels_list;
    1200    
    1201     private JButton move_level_down_button;
    1202     private JButton move_level_up_button;
    1203 
    1204     private GComboBox level_combobox;
    1205     private JTextField level_name_field;
    1206 
    1207     private JButton add_level_button;
    1208     private JButton remove_level_button;
    1209            
    1210     public MGPPLevelsPanel() {
    1211 
    1212         JPanel current_levels_panel = new JPanel();
    1213 
    1214         JLabel current_levels_label = new JLabel();
    1215         Dictionary.registerText(current_levels_label, "CDM.IndexManager.MGPP.Current_Levels");
    1216 
    1217         current_levels_list = new JList(levels_model);
    1218         current_levels_list.setVisibleRowCount(5);
    1219         current_levels_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    1220         JPanel level_movement_panel = new JPanel();
    1221 
    1222         move_level_up_button = new GLIButton("", JarTools.getImage("arrow-up.gif"));
    1223         move_level_up_button.setEnabled(false);
    1224         move_level_up_button.setMnemonic(KeyEvent.VK_U);
    1225         Dictionary.registerBoth(move_level_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
    1226 
    1227         move_level_down_button = new GLIButton("", JarTools.getImage("arrow-down.gif"));
    1228         move_level_down_button.setEnabled(false);
    1229         move_level_down_button.setMnemonic(KeyEvent.VK_D);
    1230         Dictionary.registerBoth(move_level_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
    1231 
    1232         JPanel level_spacer_panel = new JPanel();
    1233         JPanel level_body_panel = new JPanel();
    1234         JPanel level_details_panel = new JPanel();
    1235         JPanel level_labels_panel = new JPanel();
    1236         JPanel level_boxes_panel = new JPanel();
    1237 
    1238         JLabel level_name_label = new JLabel();
    1239         Dictionary.registerText(level_name_label, "CDM.IndexManager.MGPP.Level_Name");
    1240 
    1241         level_name_field = new JTextField();
    1242         level_name_field.setPreferredSize(FIELD_SIZE);
    1243         Dictionary.registerTooltip(level_name_field, "CDM.IndexManager.MGPP.Level_Name_Tooltip");
    1244 
    1245 
    1246         JLabel level_label = new JLabel();
    1247         Dictionary.registerText(level_label, "CDM.IndexManager.MGPP.Level");
    1248 
    1249         level_combobox = new GComboBox(Index.LEVEL);
    1250         level_combobox.setPreferredSize(FIELD_SIZE);
    1251         level_combobox.setBackgroundNonSelectionColor(Configuration.getColor("coloring.editable_background", false));
    1252         level_combobox.setBackgroundSelectionColor(Configuration.getColor("coloring.collection_selection_background", false));
    1253         level_combobox.setEditable(false);
    1254         level_combobox.setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
    1255         level_combobox.setTextSelectionColor(Configuration.getColor("coloring.collection_selection_foreground", false));
    1256         Dictionary.registerTooltip(level_combobox, "CDM.IndexManager.Level_Tooltip");
    1257 
    1258         JPanel level_button_panel = new JPanel();
    1259 
    1260         add_level_button = new GLIButton("CDM.IndexManager.MGPP.Add_Level");
    1261         add_level_button.setEnabled(false);
    1262         add_level_button.setMnemonic(KeyEvent.VK_A);
    1263         Dictionary.registerBoth(add_level_button, "CDM.IndexManager.MGPP.Add_Level", "CDM.IndexManager.MGPP.Add_Level_Tooltip");
    1264 
    1265         remove_level_button = new GLIButton("CDM.IndexManager.MGPP.Remove_Level");
    1266         remove_level_button.setEnabled(false);
    1267         remove_level_button.setMnemonic(KeyEvent.VK_A);
    1268         Dictionary.registerBoth(remove_level_button, "CDM.IndexManager.MGPP.Remove_Level", "CDM.IndexManager.MGPP.Remove_Level_Tooltip");
    1269 
    1270         JPanel level_empty_panel = new JPanel();
    1271 
    1272         // Connect Levels
    1273         EnableAddLevelListener level_eal = new EnableAddLevelListener();
    1274         add_level_button.addActionListener(new AddLevelActionListener());
    1275         current_levels_list.addListSelectionListener(new CurrentLevelsListSelectionListener());
    1276         level_combobox.addActionListener(level_eal);
    1277         // not editable
    1278         //((JTextField)level_combobox.getEditor().getEditorComponent()).getDocument().addDocumentListener(level_eal);
    1279         level_name_field.getDocument().addDocumentListener(level_eal);
    1280         move_level_down_button.addActionListener(new MoveLevelDownListener());
    1281         move_level_up_button.addActionListener(new MoveLevelUpListener());
    1282         remove_level_button.addActionListener(new RemoveLevelActionListener());
    1283         // Layout Levels
    1284 
    1285         level_movement_panel.setLayout(new GridLayout(2,1));
    1286         level_movement_panel.add(move_level_up_button);
    1287         level_movement_panel.add(move_level_down_button);
    1288 
    1289         current_levels_panel.setLayout(new BorderLayout());
    1290         current_levels_panel.add(current_levels_label, BorderLayout.NORTH);
    1291         current_levels_panel.add(new JScrollPane(current_levels_list), BorderLayout.CENTER);
    1292         current_levels_panel.add(level_movement_panel, BorderLayout.EAST);
    1293 
    1294         level_labels_panel.setLayout(new GridLayout(2,1));
    1295         level_labels_panel.add(level_name_label);
    1296         level_labels_panel.add(level_label);
    1297 
    1298         level_boxes_panel.setLayout(new GridLayout(2,1));
    1299         level_boxes_panel.add(level_name_field);
    1300         level_boxes_panel.add(level_combobox);
    1301 
    1302         level_details_panel.setLayout(new BorderLayout(5,0));
    1303         level_details_panel.add(level_labels_panel, BorderLayout.WEST);
    1304         level_details_panel.add(level_boxes_panel, BorderLayout.CENTER);
    1305 
    1306         level_button_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
    1307         level_button_panel.setLayout(new GridLayout(1,2,5,0));
    1308         level_button_panel.add(add_level_button);
    1309         level_button_panel.add(remove_level_button);
    1310 
    1311         level_body_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
    1312         level_body_panel.setLayout(new BorderLayout());
    1313         level_body_panel.add(level_details_panel, BorderLayout.CENTER);
    1314         level_body_panel.add(level_button_panel, BorderLayout.SOUTH);
    1315 
    1316         level_spacer_panel.setLayout(new BorderLayout());
    1317         level_spacer_panel.add(level_body_panel, BorderLayout.NORTH);
    1318         level_spacer_panel.add(level_empty_panel, BorderLayout.CENTER);
    1319 
    1320         setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    1321         setLayout(new BorderLayout());
    1322         add(current_levels_panel, BorderLayout.NORTH);
    1323         add(level_spacer_panel, BorderLayout.CENTER);
    1324     }
    1325    
    1326     public void gainFocus() {
    1327         // Ensure the level manager has at least documents assigned
    1328         if(levels_model.getSize() == 0) {
    1329         Level level = new Level(CollectionConfiguration.DOCUMENT_STR);
    1330         // Create new metadatum
    1331         CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + CollectionConfiguration.DOCUMENT_STR);
    1332         metadatum.setValue(CollectionConfiguration.DOCUMENT_STR);
    1333         // Assign new level
    1334         addLevel(level, metadatum);     
    1335         level = null;
    1336         }
    1337     }
    1338 
    1339     /** Change the enable state of the add button depending on the current value in the search type combobox. */
    1340     public void validateAddButtonLevel() {
    1341         String name = level_name_field.getText();
    1342         Object selected_object = level_combobox.getSelectedItem();
    1343         if(name.length() > 0 && selected_object != null) {
    1344         add_level_button.setEnabled(getLevel((String)selected_object) == null);
    1345         }
    1346         else {
    1347         add_level_button.setEnabled(false);
    1348         }
    1349     }
    1350 
    1351     private class AddLevelActionListener
    1352         implements ActionListener {
    1353         public void actionPerformed(ActionEvent event) {
    1354         // Retrieve the name
    1355         String name = level_name_field.getText();
    1356         // Retrieve the source
    1357         String source = (String)level_combobox.getSelectedItem();
    1358         Level level = new Level(source);
    1359         // Create new metadatum
    1360         CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source);
    1361         metadatum.setValue(name);
    1362         // Assign new level
    1363         int size = levels_model.getSize();
    1364         addLevel(level, metadatum);
    1365         current_levels_list.setSelectedValue(level, true);
    1366         add_level_button.setEnabled(false);
    1367         }
    1368     }
    1369 
    1370     private class CurrentLevelsListSelectionListener
    1371         implements ListSelectionListener {
    1372         public void valueChanged(ListSelectionEvent event) {
    1373        
    1374         if(event.getValueIsAdjusting()) {
    1375             return;
    1376         }
    1377        
    1378         Level level = (Level)current_levels_list.getSelectedValue();
    1379         if(level != null) {
    1380             String full_text = level.toString();
    1381             if(full_text.indexOf("\"") != -1) {
    1382             level_name_field.setText(level.getName());
    1383             }
    1384             String level_id = level.getLevel();
    1385             level_combobox.setSelectedItem(level_id);
    1386             move_level_down_button.setEnabled((levels_model.indexOf(level) < levels_model.getSize() - 1));
    1387             move_level_up_button.setEnabled((levels_model.indexOf(level) > 0));
    1388             remove_level_button.setEnabled(true);
    1389         }
    1390         else {
    1391             move_level_down_button.setEnabled(false);
    1392             move_level_up_button.setEnabled(false);
    1393             remove_level_button.setEnabled(false);
    1394         }
    1395         }
    1396     }
    1397    
    1398     private class EnableAddLevelListener
    1399         implements ActionListener, DocumentListener {
    1400         /** Called whenever a selection action occurs on the combobox.
    1401          * @param  event an ActionEvent containing information about the selection event
    1402          */
    1403         public void actionPerformed(ActionEvent event) {
    1404         validateAddButtonLevel();
    1405         }
    1406 
    1407         /** Gives notification that an attribute or set of attributes changed.
    1408          * @param  event a DocumentEvent containing information about the text changed
    1409          */
    1410         public void changedUpdate(DocumentEvent event) {
    1411         validateAddButtonLevel();
    1412         }
    1413 
    1414         /** Gives notification that there was an insert into the document.
    1415          * @param  event a DocumentEvent containing information about the text added
    1416          */
    1417         public void insertUpdate(DocumentEvent event) {
    1418         validateAddButtonLevel();
    1419         }
    1420 
    1421         /** Gives notification that a portion of the document has been removed.
    1422          * @param  event a DocumentEvent containing information about the text removed
    1423          */
    1424         public void removeUpdate(DocumentEvent event) {
    1425         validateAddButtonLevel();
    1426         }
    1427    
    1428     }
    1429     private class MoveLevelDownListener
    1430         implements ActionListener {
    1431         public void actionPerformed(ActionEvent event) {
    1432         // Retrieve the first selected item
    1433         Level level = (Level) current_levels_list.getSelectedValue();
    1434         moveLevel(level, false);
    1435         current_levels_list.setSelectedValue(level, true);
    1436         }
    1437     }
    1438     private class MoveLevelUpListener
    1439         implements ActionListener {
    1440         public void actionPerformed(ActionEvent event) {
    1441         // Retrieve the first selected item
    1442         Level level = (Level) current_levels_list.getSelectedValue();
    1443         moveLevel(level, true);
    1444         current_levels_list.setSelectedValue(level, true);
    1445         }
    1446     }
    1447     private class RemoveLevelActionListener
    1448         implements ActionListener {
    1449 
    1450         public void actionPerformed(ActionEvent event) {
    1451        
    1452         int i = current_levels_list.getSelectedIndex();
    1453         if (i != -1) {
    1454             Level level = (Level) current_levels_list.getSelectedValue();
    1455             CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + level.getLevel());
    1456             removeLevel(level);
    1457             if (i == current_levels_list.getModel().getSize()) {
    1458             i--;
    1459             }
    1460             current_levels_list.setSelectedIndex(i);
    1461         }       
    1462         if (i==-1) {
    1463             // Disable remove button
    1464             remove_level_button.setEnabled(false);
    1465         }
    1466         validateAddButtonLevel();
    1467         }
    1468     }
    1469 
    1470     }
    1471 
     949        new_index_prompt.dispose();
     950       
     951        }
     952    }
     953   
     954    }
     955   
     956   
    1472957}
    1473958
     959}
Note: See TracChangeset for help on using the changeset viewer.