source: gli/trunk/src/org/greenstone/gatherer/gui/EnrichPane.java@ 18947

Last change on this file since 18947 was 18593, checked in by kjdon, 15 years ago

GLI three modes change: file tree filters are now editable in librarian mode, and regex plugin/classifier arguments are now shown in librarian mode

  • Property svn:keywords set to Author Date Id Revision
File size: 16.3 KB
RevLine 
[6840]1/**
[9856]2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
[6840]5 * University of Waikato, New Zealand.
6 *
[9856]7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 * Based on code by John Thompson
[6840]9 *
[9856]10 * Copyright (C) 2005 New Zealand Digital Library Project
[6840]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.
[9856]25 *############################################################################
[6840]26 */
[9856]27
[6840]28package org.greenstone.gatherer.gui;
29
[8313]30
[6840]31import java.awt.*;
32import java.awt.event.*;
33import java.io.*;
34import java.util.*;
35import javax.swing.*;
36import javax.swing.event.*;
[9856]37import javax.swing.text.*;
[6840]38import javax.swing.tree.*;
39import org.greenstone.gatherer.Configuration;
[8236]40import org.greenstone.gatherer.DebugStream;
[6840]41import org.greenstone.gatherer.Dictionary;
42import org.greenstone.gatherer.Gatherer;
[8846]43import org.greenstone.gatherer.collection.CollectionTree;
[8783]44import org.greenstone.gatherer.collection.CollectionTreeNode;
[6840]45import org.greenstone.gatherer.gui.tree.DragTree;
[8313]46import org.greenstone.gatherer.metadata.MetadataElement;
47import org.greenstone.gatherer.metadata.MetadataValue;
48import org.greenstone.gatherer.metadata.MetadataValueTableEntry;
49import org.greenstone.gatherer.metadata.MetadataValueTreeNode;
[10547]50import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
[8313]51
52
[8695]53/** Provides a view of controls for the editing of metadata.
[8313]54 */
[6840]55public class EnrichPane
56 extends JPanel
[9856]57 implements TreeSelectionListener
[8802]58{
[6840]59 static private Dimension MINIMUM_SIZE = new Dimension(100, 100);
[9856]60 static private Dimension COLLECTION_TREE_SIZE = new Dimension(250, 500);
[6840]61
[13801]62 private boolean has_focus = false;
[9856]63 /** The collection tree. */
64 private CollectionTree collection_tree = null;
[8313]65 /** The currently reported selection. */
[8783]66 private CollectionTreeNode[] file_nodes = null;
[11622]67 /** Used to dynamically filter the collection tree. */
[9856]68 private Filter collection_filter = null;
[6840]69 /** The label at the top of the collection tree, which shows the collection name. */
70 private JLabel collection_label;
[11626]71 /** The panel that contains the collection tree. */
72 private JPanel collection_pane = null;
73 /** The scrollable area into which the collection tree is placed. */
74 private JScrollPane collection_scroll = null;
[9856]75 /** The splitpane dividing the collection tree and the metadata editing controls. */
[6840]76 private JSplitPane external_split;
[9856]77 /** The metadata value table shows the metadata values that are currently assigned to a file. */
78 private MetadataValueTablePane metadata_value_table_pane = null;
79 /** The metadata value tree shows the metadata values that are currently assigned to a metadata element. */
80 private MetadataValueTreePane metadata_value_tree_pane = null;
[6840]81
[8313]82
[11629]83 public EnrichPane()
[6840]84 {
[18370]85 this.setComponentOrientation(Dictionary.getOrientation());
86 // Create the metadata value tree pane
87 metadata_value_tree_pane = new MetadataValueTreePane();
[9856]88 metadata_value_tree_pane.addMetadataValueTreeSelectionListener(new MetadataValueTreeSelectionListener());
[6840]89
[9856]90 // Create metadata value table pane
[18370]91 metadata_value_table_pane = new MetadataValueTablePane();
[9856]92 metadata_value_table_pane.addMetadataValueTableListSelectionListener(new MetadataValueTableListSelectionListener());
93 metadata_value_table_pane.addMetadataValueTableMouseListener(new MetadataValueTableMouseListener());
94 metadata_value_table_pane.addMetadataValueTextFieldDocumentListener(new MetadataValueTextFieldDocumentListener());
95 metadata_value_table_pane.addMetadataValueTextFieldKeyListener(new MetadataValueTextFieldKeyListener());
[6840]96 }
97
98
99 /** Some actions can only occur after this panel has been displayed on-screen, so this method is provided to do exactly that. Such actions include the proportioning of the split panes and the setting of table column widths.
100 */
[8313]101 public void afterDisplay()
102 {
[18370]103 if (Dictionary.getOrientation().isLeftToRight()){
104 external_split.setDividerLocation(0.3);
105 }else{
106 external_split.setDividerLocation(0.7);
107 }
[6840]108 }
[8313]109
110
[6840]111 /** Used to create, connect and layout the components to be shown on this control panel.
112 * @see org.greenstone.gatherer.Gatherer
113 * @see org.greenstone.gatherer.file.FileOpenActionListener
114 * @see org.greenstone.gatherer.gui.Filter
115 */
[8313]116 public void display()
117 {
[12145]118 JPanel left_hand_pane = new JPanel(new BorderLayout());
[18370]119 left_hand_pane.setComponentOrientation(Dictionary.getOrientation());
[12145]120 GLIButton metadata_set_button = new GLIButton(Dictionary.get("EnrichPane.ManageMetadataSets"), Dictionary.get("EnrichPane.ManageMetadataSets_Tooltip"));
121 metadata_set_button.addActionListener(new ActionListener() {
122 public void actionPerformed(ActionEvent event) {
123 MetadataSetDialog msd = new MetadataSetDialog();
124 if (msd.setsChanged()) {
125 valueChanged(null);
126 }
127 }
128 });
129
[11761]130 // Collection Tree
[11626]131 collection_pane = new JPanel(new BorderLayout());
[18370]132 // collection_pane.setComponentOrientation(Dictionary.getOrientation());
[6840]133 collection_pane.setMinimumSize(MINIMUM_SIZE);
[9856]134 collection_pane.setPreferredSize(COLLECTION_TREE_SIZE);
[6840]135
[12119]136 collection_label = new JLabel(Dictionary.get("Collection.No_Collection"));
[18370]137 collection_label.setComponentOrientation(Dictionary.getOrientation());
[6840]138 collection_label.setOpaque(true);
139
[11627]140 collection_tree = Gatherer.c_man.getCollectionTree();
[6840]141 collection_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
[18370]142 collection_tree.addTreeSelectionListener(this);
143 collection_tree.setComponentOrientation(Dictionary.getOrientation());
[11619]144 collection_filter = collection_tree.getFilter();
[11761]145 external_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
[18370]146 external_split.setComponentOrientation(Dictionary.getOrientation());
[6840]147 // Layout
148 collection_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(3,3,3,3), BorderFactory.createLoweredBevelBorder()));
149 collection_pane.setMinimumSize(MINIMUM_SIZE);
150 collection_pane.setPreferredSize(new Dimension(Gatherer.g_man.getSize().width / 3, Gatherer.g_man.getSize().height));
[18370]151 collection_pane.setComponentOrientation(Dictionary.getOrientation());
[6840]152 // Collection Pane
153 collection_pane.add(collection_label, BorderLayout.NORTH);
154
[9856]155 JSplitPane metadata_editing_pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
156 metadata_editing_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
157 metadata_editing_pane.setDividerSize(8);
[18370]158 metadata_editing_pane.setComponentOrientation(Dictionary.getOrientation());
159
[9856]160 metadata_editing_pane.add(metadata_value_table_pane, JSplitPane.TOP);
161 metadata_editing_pane.add(metadata_value_tree_pane, JSplitPane.BOTTOM);
162 metadata_editing_pane.setDividerLocation(250);
[6840]163
[12145]164 left_hand_pane.add(collection_pane, BorderLayout.CENTER);
165 left_hand_pane.add(metadata_set_button, BorderLayout.SOUTH);
[18370]166 if (Dictionary.getOrientation().isLeftToRight()){
167 external_split.add(left_hand_pane, JSplitPane.LEFT);
168 external_split.add(metadata_editing_pane, JSplitPane.RIGHT);
169 }else{
170 external_split.add(left_hand_pane, JSplitPane.RIGHT);
171 external_split.add(metadata_editing_pane, JSplitPane.LEFT);
172 }
[6840]173
[12145]174
175
[6840]176 this.setLayout(new BorderLayout());
177 this.add(external_split, BorderLayout.CENTER);
178 }
179
180
[9856]181 /** Called to inform this pane that it has just gained focus as an effect of the user clicking on its tab
[6840]182 */
[8313]183 public void gainFocus()
184 {
[13801]185 // Remember that we currently have focus
186 has_focus = true;
187
[11626]188 // Add the collection tree and filter back into this pane
189 collection_scroll = new JScrollPane(collection_tree);
190 collection_pane.add(collection_scroll, BorderLayout.CENTER);
191 collection_pane.add(collection_filter, BorderLayout.SOUTH);
192
[8313]193 // Select the first node in the tree if nothing is already selected
[11825]194 if (collection_tree.getSelectionPaths() == null && collection_tree.getRowCount() > 0) {
[8313]195 collection_tree.setImmediate(true);
196 collection_tree.setSelectionRow(0);
197 collection_tree.setImmediate(false);
[8359]198 return;
[6840]199 }
200
[8313]201 // Force all of the controls to be updated
[9856]202 valueChanged(null);
[6840]203 }
204
205
[10387]206 /** Called to inform this pane that it has just lost focus as an effect of the user clicking on another tab
207 */
208 public void loseFocus()
209 {
[10604]210 // Very important: make sure metadata value is saved before leaving the pane
211 metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
212
[13705]213 // Make sure all the metadata has been saved to file
214 MetadataXMLFileManager.saveMetadataXMLFiles();
[11626]215
216 // Remove the collection tree and filter from this pane so it can be added to the Gather pane
217 collection_pane.remove(collection_scroll);
218 collection_pane.remove(collection_filter);
[13801]219
220 // Remember that we no longer have focus
221 has_focus = false;
[10387]222 }
223
224
[6840]225 /** Called whenever the detail mode changes to ensure the filters are at an appropriate level (ie only editable by those that understand regular expression matching)
226 * @param mode the mode level as an int
227 */
[8313]228 public void modeChanged(int mode)
229 {
[18593]230 collection_filter.setEditable(mode >= Configuration.LIBRARIAN_MODE);
[6840]231 }
232
233
[8813]234 /** Refresh this pane, depending on what has just happened (refresh_reason). */
235 public void refresh(int refresh_reason, boolean collection_loaded)
[8353]236 {
[8813]237 if (collection_loaded) {
238 // Update collection label
[12119]239 collection_label.setText(Dictionary.get("Collection.Collection"));
[8353]240 collection_label.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
241 collection_label.setForeground(Configuration.getColor("coloring.collection_heading_foreground", false));
242
[8813]243 // Update collection tree
244 if (refresh_reason == Gatherer.COLLECTION_OPENED) {
[8846]245 collection_tree.setModel(Gatherer.c_man.getCollectionTreeModel());
[8354]246 }
[8813]247
248 // Update collection filter
249 collection_filter.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
[8353]250 }
251 else {
[8813]252 // Update collection label
[12119]253 collection_label.setText(Dictionary.get("Collection.No_Collection"));
[8353]254 collection_label.setBackground(Color.lightGray);
255 collection_label.setForeground(Color.black);
[8354]256
[8813]257 // Update collection tree
258 collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error")));
259
260 // Update collection filter
261 collection_filter.setBackground(Color.lightGray);
[8353]262 }
263
[8813]264 // Enable or disable the controls
265 collection_tree.setEnabled(collection_loaded);
266 collection_filter.setEnabled(collection_loaded);
267
268 // Force the metadata table to be rebuilt (for switching extracted metadata on or off)
269 if (refresh_reason == Gatherer.PREFERENCES_CHANGED) {
[9856]270 metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
[8813]271 }
[8353]272 }
273
274
[18199]275 /** Allows other classes to request the enrich pane to prepare for metadata
276 * saving.
277 * @author John Thompson, DL Consulting Ltd
278 */
279 public void stopEditingAndRebuild()
280 {
281 // Update the metadata value table (and consequently, the metadata value tree)
282 metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
283 }
284 /** stopEditingAndRebuild() **/
285
286 /** Called whenever the collection tree selection changes. This causes the metadata value table to be rebuilt. */
287 public void valueChanged(TreeSelectionEvent event)
[8313]288 {
[13801]289 // If we haven't got focus then it must have been a selection in the Gather pane, so don't bother rebuilding
290 if (has_focus == false) {
291 return;
292 }
293
[8313]294 // Nothing selected in the collection tree
295 if (collection_tree.getSelectionCount() == 0) {
296 file_nodes = null;
[6840]297 }
298
[8313]299 // Some files selected in the collection tree
[6840]300 else {
[8313]301 TreePath paths[] = collection_tree.getSelectionPaths();
[8783]302 file_nodes = new CollectionTreeNode[paths.length];
[8313]303 for (int i = 0; i < paths.length; i++) {
[8783]304 file_nodes[i] = (CollectionTreeNode) paths[i].getLastPathComponent();
[6840]305 }
306 }
[8313]307
308 // Update the metadata value table (and consequently, the metadata value tree)
[9856]309 metadata_value_table_pane.stopEditingAndRebuild(file_nodes);
[6840]310 }
311
[8313]312
[9856]313 private class MetadataValueTableListSelectionListener
314 implements ListSelectionListener
[8313]315 {
[9856]316 public void valueChanged(ListSelectionEvent list_selection_event)
[8313]317 {
[9856]318 // We only want to handle one event per selection, so wait for the value to stabilise
319 if (list_selection_event.getValueIsAdjusting()) {
320 return;
[9334]321 }
[9331]322
[9856]323 // Update the metadata value tree for the current table selection
324 metadata_value_tree_pane.rebuild(metadata_value_table_pane.getSelectedMetadataValueTableEntry());
[6840]325 }
326 }
327
328
[9856]329 private class MetadataValueTableMouseListener
330 extends MouseAdapter
[8313]331 {
[9856]332 public void mouseClicked(MouseEvent mouse_event)
[8313]333 {
[9856]334 // We're only interested in clicks on the inherited column
335 if (metadata_value_table_pane.isMouseEventForInheritedMetadataValueTableColumn(mouse_event) == false) {
336 return;
337 }
[6840]338
[9856]339 // If the selected metadata is inherited, switch to the folder it came from
340 MetadataValueTableEntry selected_metadata_value_table_entry = metadata_value_table_pane.getSelectedMetadataValueTableEntry();
341 if (selected_metadata_value_table_entry.isInheritedMetadata()) {
342 collection_tree.setSelection(selected_metadata_value_table_entry.getFolderMetadataInheritedFrom());
[9334]343 }
[8313]344 }
345 }
[6840]346
347
[9856]348 private class MetadataValueTextFieldDocumentListener
349 implements DocumentListener
[8313]350 {
[9856]351 /** Gives notification that an attribute or set of attributes changed */
352 public void changedUpdate(DocumentEvent document_event) {
353 validate(document_event);
354 }
[9331]355
[9856]356 /** Gives notification that there was an insert into the document */
357 public void insertUpdate(DocumentEvent document_event) {
358 validate(document_event);
[9331]359 }
360
[9856]361 /** Gives notification that a portion of the document has been removed */
362 public void removeUpdate(DocumentEvent document_event) {
363 validate(document_event);
364 }
365
366
367 /** Ensures that the value tree is updated in response to changes in the value text field */
368 private void validate(DocumentEvent document_event)
[8313]369 {
[9334]370 try {
[9856]371 Document document = document_event.getDocument();
372 String metadata_value_string = document.getText(0, document.getLength());
373 metadata_value_tree_pane.selectBestPathForMetadataValue(metadata_value_string);
[9334]374 }
375 catch (Exception exception) {
376 DebugStream.printStackTrace(exception);
377 }
[6840]378 }
[8313]379 }
[6840]380
[8313]381
[9856]382 private class MetadataValueTextFieldKeyListener
383 extends KeyAdapter
[8313]384 {
[9856]385 /** Gives notification of key events on the text field */
386 public void keyPressed(KeyEvent key_event)
[8313]387 {
[9856]388 // Tab: Auto-complete what is selected in the metadata value tree
389 if (key_event.getKeyCode() == KeyEvent.VK_TAB) {
390 MetadataValueTreeNode selected_metadata_value_tree_node = metadata_value_tree_pane.getSelectedMetadataValueTreeNode();
391 if (selected_metadata_value_tree_node != null) {
392 metadata_value_table_pane.setMetadataValueTextFieldValue(selected_metadata_value_tree_node.getFullValue());
[8313]393 }
[6840]394
[9856]395 // We do not want this event to be processed by the table also
396 key_event.consume();
[8313]397 }
[6840]398
[9856]399 // Enter: save the current value then add a blank row for the selected metadata element
400 if (key_event.getKeyCode() == KeyEvent.VK_ENTER) {
401 metadata_value_table_pane.stopEditingAndAddBlankRowForSelectedMetadataElement();
[8364]402 }
403 }
[7098]404 }
405
406
[9856]407 private class MetadataValueTreeSelectionListener
408 implements TreeSelectionListener
[8313]409 {
[9856]410 public void valueChanged(TreeSelectionEvent tree_selection_event)
[6840]411 {
[9856]412 // When a node is selected in the tree, fill the metadata value text field with the selected node's value
413 MetadataValueTreeNode selected_metadata_value_tree_node = metadata_value_tree_pane.getSelectedMetadataValueTreeNode();
414 if (selected_metadata_value_tree_node != null) {
415 metadata_value_table_pane.setMetadataValueTextFieldValue(selected_metadata_value_tree_node.getFullValue());
[6840]416 }
417 }
418 }
419}
Note: See TracBrowser for help on using the repository browser.