source: trunk/gli/src/org/greenstone/gatherer/gems/GEMS.java@ 10462

Last change on this file since 10462 was 10462, checked in by mdewsnip, 19 years ago

More GEMS tidy ups: no classes now import the Gatherer class.

  • Property svn:keywords set to Author Date Id Revision
File size: 94.8 KB
Line 
1 /**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at th * University of Waikato, New Zealand.
6 *
7 * <BR><BR>
8 *
9 * Author: John Thompson, Greenstone Digital Library, University of Waikato
10 *
11 * <BR><BR>
12 *
13 * Copyright (C) 1999 New Zealand Digital Library Project
14 *
15 * <BR><BR>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * <BR><BR>
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * <BR><BR>
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 *############################################## ##########################
35 */
36package org.greenstone.gatherer.gems;
37
38import java.awt.*;
39import java.awt.event.*;
40import java.io.File;
41import java.io.PrintStream;
42import java.io.FileInputStream;
43import java.io.BufferedReader;
44import java.io.FileOutputStream;
45import java.io.OutputStreamWriter;
46import java.io.DataInputStream;
47import java.io.IOException;
48import java.io.InputStreamReader;
49import java.io.PrintWriter;
50import java.util.*;
51import javax.swing.*;
52import java.lang.String;
53import javax.swing.event.*;
54import javax.swing.filechooser.*;
55import javax.swing.text.*;
56import javax.swing.tree.*;
57import org.greenstone.gatherer.Configuration;
58import org.greenstone.gatherer.DebugStream;
59import org.greenstone.gatherer.Dictionary;
60import org.greenstone.gatherer.GetOpt;
61import org.greenstone.gatherer.gui.GComboBox;
62import org.greenstone.gatherer.gui.GLIButton;
63import org.greenstone.gatherer.gui.HelpFrame;
64import org.greenstone.gatherer.gui.ModalDialog;
65import org.greenstone.gatherer.gui.NonWhitespaceField;
66import org.greenstone.gatherer.util.Codec;
67import org.greenstone.gatherer.util.JarTools;
68import org.greenstone.gatherer.util.Utility;
69import org.greenstone.gatherer.util.XMLTools;
70import org.w3c.dom.*;
71
72
73
74/** Provides a GUI and relevant suite of tools for the editing of the metadata set associated with this collection. Again I have tried to capture a file manager type feel, with a tree showing the various set-element relations to the left of the dialog, and the right side showing details on the current tree selection. When a set is selected these details include a list of attributes, while when an element is selected this list is joined by another showing assigned values. In order for the editor to be stable and consistant with the rest of the tool, care must be taken for fire appropriate events whenever the sets are changed. There is also the addded complexity of determining what actions have to occur in order for a users edit of an assigned value to be completed, i.e. if the user chooses to remove a value then a call must be made to record_set.root.removeMetadata() to ensure all such values are actually removed, so it is not enough just to remove the value from the value model.
75 * @author John Thompson, Greenstone Digital Library, University of Waikato
76 * @version 2.3b
77 */
78public class GEMS
79 extends JFrame
80{
81 static final public int ADD_SET = 0;
82 static final public int NORMAL = 1;
83 static final public int REMOVE_SET = 2;
84
85 /** The default size of the editor dialog. */
86 static final private Dimension ADD_ELEMENT_SIZE = new Dimension(400,125);
87 static final private Dimension RENAME_ELEMENT_SIZE = new Dimension(400, 95);
88 static final private Dimension ADD_SET_SIZE = new Dimension(400,150);
89 static final private Dimension RENAME_SET_SIZE = new Dimension(400,120);
90 static final private Dimension OPEN_SETS_SIZE = new Dimension(400,135);
91 static final private Dimension ADD_OR_EDIT_ATTRIBUTE_SIZE = new Dimension(600,325);
92 static final private Dimension COMPONENT_SIZE = new Dimension(300,30);
93 static final private Dimension SIZE = new Dimension(800,480);
94 static final private String BLANK = "blank";
95 static final private String ELEMENT = "element";
96 static final private String SET = "set";
97
98 static final public String METADATA_SET_TEMPLATE = "xml" + File.separator + "template.mds";
99
100 //all of our popup menu items
101 static final public int T_COLLECTION = 0;
102 static final public int T_ELEMENT = 1;
103 static final public int T_SET = 4;
104
105 //static final public String MAX_LOADED_SETS = 64;
106 static public Configuration config = null;
107 private MetadataSetManager msm = new MetadataSetManager(this);
108
109 public AddElementActionListener add_element_action_listener = null;
110 public AddSetActionListener add_set_action_listener = null;
111 /** The class used to handle add or edit attribute actions has to be globally available so that we can dispose of its dialog properly. */
112 public AddOrEditAttributeActionListener add_or_edit_attribute_action_listener = null;
113 private boolean ignore = false;
114 /** A card layout is used to switch between the two differing detail views. */
115 private CardLayout card_layout = null;
116
117 /** Um, the size of the screen I'd guess. */
118 private Dimension screen_size = null;
119 private ElementWrapper current_element = null;
120 /** A reference to ourselves so our inner classes can dispose of us. */
121 private GEMS self = null;
122 private int current_attribute = -1;
123 private int current_attribute_type = -1;
124
125 //private JLabel element_name = null;
126 private JLabel set_name = null;
127 private JScrollPane element_attributes_scroll = null;
128 private JScrollPane set_attributes_scroll = null;
129 private JPanel details_pane = null;
130 private GEMSModel model = null;
131 private GEMSNode current_node = null;
132 private MetadataSet current_set = null;
133 public RemoveSetActionListener remove_set_action_listener;
134 private SmarterTable element_attributes = null;
135 private SmarterTable set_attributes = null;
136 public org.w3c.dom.Element rootelement;
137
138 //PopupListener provides right-click functionality to any component that needs it
139 //It is a centralized manager for all popups, then we use evt.Source() and determine where the
140 //event was performed
141 private PopupListener popupListener = null;
142
143 /** A tree that represents the current metadata sets associated with this collection. */
144 private SmarterTree mds_tree = null;
145 private String dialog_options[] = null;
146 private boolean atLeastOneSetChanged = false;
147
148 static public void main(String[] args)
149 {
150 // Parse arguments
151 GetOpt go = new GetOpt(args);
152
153 if (go.debug) {
154 DebugStream.enableDebugging();
155
156 Calendar now = Calendar.getInstance();
157 String debug_file_path = "debug" + now.get(Calendar.DATE) + "-" + now.get(Calendar.MONTH) + "-" + now.get(Calendar.YEAR) + ".txt";
158
159 // Debug file is created in the GLI directory
160 DebugStream.println("Debug file path: " + debug_file_path);
161 DebugStream.setDebugFile(debug_file_path);
162 }
163
164 GEMS GEMS;
165 GEMS = new GEMS(go.gsdl_path);
166 }
167
168
169 /** Constructor.
170 * @param set a MetadataSet that should be initially selected
171 * @param action a systematic action that should be performed
172 */
173 public GEMS(String gsdl_path)
174 {
175 // Determine the GLI user directory path
176 String gli_user_directory_path = System.getProperty("user.home") + File.separator;
177 if (Utility.isWindows()) {
178 gli_user_directory_path += "Application Data" + File.separator + "Greenstone" + File.separator + "GLI" + File.separator;
179 }
180 else {
181 gli_user_directory_path += ".gli" + File.separator;
182 }
183
184 //Load configuration file
185 this.self = this;
186 JarTools.initialise(this);
187 config = new Configuration(gli_user_directory_path, gsdl_path, null, null, null);
188
189 // Read Dictionary
190 new Dictionary(Configuration.getLocale("general.locale", true), Configuration.getFont("general.font", true));
191
192 this.dialog_options = new String[2];
193 this.screen_size = config.screen_size;
194
195 // Initialise some common images
196 popupListener = new PopupListener(this);
197
198 // Load help
199 HelpFrame help = new HelpFrame();
200
201 dialog_options[0] = Dictionary.get("General.OK");
202 dialog_options[1] = Dictionary.get("General.Cancel");
203
204 // Load all the core metadata sets (in the GLI "metadata" directory)
205 model = new GEMSModel();
206 File metadata_directory = new File(getGLIMetadataDirectoryPath());
207 if (metadata_directory.exists()) {
208 // Load just those .mds files in this directory, and return them
209 File[] directory_files = metadata_directory.listFiles();
210 for (int i = 0; i < directory_files.length; i++) {
211 File child_file = directory_files[i];
212 if (!child_file.isDirectory() && child_file.getName().endsWith(".mds")) {
213 MetadataSet metadata_set = msm.loadMetadataSet(child_file);
214 model.add(null, metadata_set, GEMSNode.SET);
215 }
216 }
217 }
218
219 // Creation
220 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
221 setSize(SIZE);
222 setJMenuBar(new GEMSMenuBar());
223 Dictionary.setText(this, "GEMS.Title");
224
225 JPanel content_pane = (JPanel) getContentPane();
226 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
227 JPanel upper_pane = new JPanel();
228 upper_pane.setOpaque(false);
229 JPanel set_details_pane = new JPanel();
230 set_details_pane.setOpaque(false);
231 JPanel set_name_pane = new JPanel();
232 set_name_pane.setOpaque(false);
233 JLabel set_name_label = new JLabel();
234 set_name_label.setOpaque(false);
235 JPanel element_details_pane = new JPanel();
236 element_details_pane.setOpaque(false);
237 JPanel element_inner_pane = new JPanel();
238 element_inner_pane.setOpaque(false);
239 JPanel blank_pane = new JPanel(); // Some blank panel
240 blank_pane.setOpaque(false);
241
242 details_pane = new JPanel();
243 details_pane.setOpaque(false);
244 card_layout = new CardLayout();
245 set_name = new JLabel();
246
247 JPanel mds_tree_pane = new JPanel();
248 mds_tree_pane.setOpaque(false);
249 mds_tree_pane.setPreferredSize(new Dimension(300,500));
250
251 mds_tree = new SmarterTree(model);
252 mds_tree.setCellRenderer(new GEMSTreeCellRenderer());
253 mds_tree.setRootVisible(false);
254 mds_tree.setBackground(config.getColor("coloring.collection_tree_background", false));
255 mds_tree.setForeground(config.getColor("coloring.collection_tree_foreground", false));
256 mds_tree.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
257 mds_tree.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
258 //add popupevent handler for tree items
259 mds_tree.addMouseListener(popupListener);
260 mds_tree.addKeyListener(new KeyPressedHandler());
261 mds_tree.addTreeSelectionListener(new MDSTreeSelectionListener());
262
263 JPanel set_attributes_pane = new JPanel();
264 set_attributes_pane.setOpaque(false);
265 set_attributes_scroll = new JScrollPane();
266 set_attributes_scroll.getViewport().setBackground(config.getColor("coloring.collection_tree_background", false));
267 set_attributes_scroll.setOpaque(true);
268 set_attributes = new SmarterTable();
269 set_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
270 set_attributes.setBackground(config.getColor("coloring.collection_tree_background", false));
271 set_attributes.setForeground(config.getColor("coloring.collection_tree_foreground", false));
272 set_attributes.setHeadingBackground(config.getColor("coloring.collection_heading_background", false));
273 set_attributes.setHeadingForeground(config.getColor("coloring.collection_heading_foreground", false));
274 set_attributes.setOpaque(false);
275 set_attributes.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
276 set_attributes.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
277 set_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
278 set_attributes.addMouseListener(popupListener);
279 set_attributes.addMouseListener(new AddOrEditAttributeActionListener());
280 set_attributes.addKeyListener(new RemoveAttributeActionListener()); //Listen for DELETE key
281 set_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(set_attributes));
282
283 JPanel element_attributes_pane = new JPanel();
284 element_attributes_pane.setOpaque(false);
285 element_attributes_scroll = new JScrollPane();
286 element_attributes_scroll.getViewport().setBackground(config.getColor("coloring.collection_tree_background", false));
287 element_attributes_scroll.setOpaque(true);
288 element_attributes = new SmarterTable();
289 element_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
290 element_attributes.setBackground(config.getColor("coloring.collection_tree_background", false));
291 element_attributes.setForeground(config.getColor("coloring.collection_tree_foreground", false));
292 element_attributes.setHeadingBackground(config.getColor("coloring.collection_heading_background", false));
293 element_attributes.setHeadingForeground(config.getColor("coloring.collection_heading_foreground", false));
294 element_attributes.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
295 element_attributes.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
296 element_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
297 element_attributes.addMouseListener(popupListener);
298 element_attributes.addMouseListener(new AddOrEditAttributeActionListener());
299 element_attributes.addKeyListener(new RemoveAttributeActionListener()); //For the DELETE key
300 element_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(element_attributes));
301
302 add_element_action_listener = new AddElementActionListener();
303 add_set_action_listener = new AddSetActionListener();
304 add_or_edit_attribute_action_listener = new AddOrEditAttributeActionListener();
305 remove_set_action_listener = new RemoveSetActionListener();
306
307 // Layout
308 mds_tree_pane.setLayout(new BorderLayout());
309 mds_tree_pane.add(new JScrollPane(mds_tree), BorderLayout.CENTER);
310
311 //Set panes
312 set_name_pane.setLayout(new BorderLayout());
313 set_name_pane.add(set_name_label, BorderLayout.WEST);
314 set_name_pane.add(set_name, BorderLayout.CENTER);
315
316 set_attributes_scroll.setViewportView(set_attributes);
317 set_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
318 set_attributes_pane.setLayout(new BorderLayout());
319 set_attributes_pane.add(set_attributes_scroll, BorderLayout.CENTER);
320
321 set_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Set_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
322 set_details_pane.setLayout(new BorderLayout());
323 set_details_pane.add(set_name_pane, BorderLayout.NORTH);
324 set_details_pane.add(set_attributes_pane, BorderLayout.CENTER);
325
326 //Element panes
327 element_attributes_scroll.setViewportView(element_attributes);
328 element_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
329 element_attributes_pane.setLayout(new BorderLayout());
330 element_attributes_pane.add(element_attributes_scroll, BorderLayout.CENTER);
331
332 element_inner_pane.setLayout(new BorderLayout());
333 element_inner_pane.add(element_attributes_pane);
334
335 element_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Element_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
336 element_details_pane.setLayout(new BorderLayout());
337 element_details_pane.add(element_inner_pane, BorderLayout.CENTER);
338
339 //General panes
340 details_pane.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
341 details_pane.setLayout(card_layout);
342 details_pane.add(blank_pane, BLANK);
343 details_pane.add(set_details_pane, SET);
344 details_pane.add(element_details_pane, ELEMENT);
345
346 upper_pane.setLayout(new BorderLayout());
347 upper_pane.add(mds_tree_pane, BorderLayout.WEST);
348 upper_pane.add(details_pane, BorderLayout.CENTER);
349
350 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
351 content_pane.setLayout(new BorderLayout());
352 content_pane.add(upper_pane, BorderLayout.CENTER);
353
354 // initialise the selection
355 mds_tree.setSelectionRow(0);
356 // Display
357 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
358 setVisible(true);
359 }
360
361
362 private void exit()
363 {
364 if(atLeastOneSetChanged == true)
365 {
366 int result = JOptionPane.showConfirmDialog(self, Dictionary.get("GEMS.Confirm_Exit_Save", Dictionary.get("GEMS.Element")), Dictionary.get("GEMS.Confirm_Exit_Save_Title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
367
368 if(result == 0)
369 {
370 DebugStream.closeDebugStream();
371 msm.save();
372 System.exit(0);
373 }
374 else if(result == 1)
375 {
376 DebugStream.closeDebugStream();
377 System.exit(0);
378 }
379 else if(result == 2)
380 {
381 //do nothing
382 }
383 }
384 else
385 {
386 //Just exit
387 DebugStream.closeDebugStream();
388 System.exit(0);
389 }
390 }
391
392
393 static public String getGLIDirectoryPath()
394 {
395 return System.getProperty("user.dir") + File.separator;
396 }
397
398
399 static public String getGLIMetadataDirectoryPath()
400 {
401 return getGLIDirectoryPath() + "metadata" + File.separator;
402 }
403
404
405 private class GEMSMenuBar
406 extends JMenuBar
407 implements ActionListener
408 {
409 private JMenu file = null;
410 private JMenu edit = null;
411 private JMenu help = null;
412
413 public JMenuItem file_exit = null;
414 public JMenuItem file_new = null;
415 public JMenuItem file_open = null;
416 public JMenuItem file_save = null;
417 public JMenuItem edit_copy = null;
418 public JMenuItem edit_cut = null;
419 public JMenuItem edit_paste = null;
420 public JMenuItem help_help = null;
421 public JMenuItem file_delete = null;
422 public JMenuItem file_preferences = null;
423 public GEMSMenuBar()
424 {
425 file = new JMenu();
426 file.setMnemonic(KeyEvent.VK_F);
427 Dictionary.registerText(file, "Menu.File");
428
429 file_exit = new JMenuItem();
430 file_exit.addActionListener(this);
431 file_exit.setMnemonic(KeyEvent.VK_X);
432 Dictionary.registerText(file_exit, "Menu.File_Exit");
433
434 file_new = new JMenuItem();
435 file_new.addActionListener(this);
436 file_new.setMnemonic(KeyEvent.VK_N);
437 Dictionary.registerText(file_new, "Menu.File_New");
438
439 file_open = new JMenuItem();
440 file_open.addActionListener(this);
441 file_open.setMnemonic(KeyEvent.VK_O);
442 Dictionary.registerText(file_open, "Menu.File_Open");
443
444 file_save = new JMenuItem();
445 file_save.addActionListener(this);
446 file_save.setMnemonic(KeyEvent.VK_S);
447 Dictionary.registerText(file_save, "Menu.File_Save");
448
449 file_delete = new JMenuItem();
450 file_delete.addActionListener(new KeyPressedHandler()); //KeyPressedHandler handles deleting stuff.
451 file_delete.setMnemonic(KeyEvent.VK_S);
452 Dictionary.registerText(file_delete, "Menu.File_Delete");
453
454 file_preferences = new JMenuItem();
455 file_preferences.addActionListener(this);
456 file_preferences.setMnemonic(KeyEvent.VK_S);
457 Dictionary.registerText(file_preferences, "Menu.File_Options");
458
459 // Layout (file menu)
460 file.add(file_new);
461 file.add(file_open);
462 file.add(file_save);
463 file.add(file_delete);
464 file.add(new JSeparator());
465 file.add(file_preferences);
466 file.add(new JSeparator());
467 file.add(file_exit);
468
469 // Edit menu
470 edit = new JMenu();
471 edit.setMnemonic(KeyEvent.VK_E);
472 Dictionary.registerText(edit, "Menu.Edit");
473
474 edit_cut = new JMenuItem();
475 edit_cut.addActionListener(this);
476 edit_cut.setMnemonic(KeyEvent.VK_X);
477 Dictionary.registerText(edit_cut, "Menu.Edit_Cut");
478
479 edit_copy = new JMenuItem();
480 edit_copy.addActionListener(this);
481 edit_copy.setMnemonic(KeyEvent.VK_C);
482 Dictionary.registerText(edit_copy, "Menu.Edit_Copy");
483
484 edit_paste = new JMenuItem();
485 edit_paste.addActionListener(this);
486 edit_paste.setMnemonic(KeyEvent.VK_V);
487 Dictionary.registerText(edit_paste, "Menu.Edit_Paste");
488
489 // Layout (edit menu)
490 edit.add(edit_cut);
491 edit.add(edit_copy);
492 edit.add(edit_paste);
493
494 // Help menu. Is not used! --Matthew
495 // help = new JMenu();
496 // help.setIcon(JarTools.getImage("help.gif"));
497 // Dictionary.setText(help, "Menu.Help");
498
499 //help_help = new JMenuItem();
500 //help_help.addActionListener(this);
501 //Dictionary.registerText(help_help, "Menu.Help");
502
503 // Layout (help menu)
504 //help.add(help_help);
505
506 // Layout (menu bar)
507 this.add(file);
508 this.add(Box.createHorizontalStrut(15));
509 this.add(edit);
510 this.add(Box.createHorizontalGlue());
511 //this.add(help);
512 }
513
514
515 public void actionPerformed(ActionEvent event)
516 {
517 Object event_source = event.getSource();
518
519 // File -> New
520 if (event_source == file_new) {
521 AddSetActionListener rah = new AddSetActionListener();
522 rah.setVisible(true);
523 // rah.show();
524
525 return;
526 }
527
528 // File -> Open
529 if (event_source == file_open) {
530
531 //we first launch the dialog to determine where the jfilechooser should be opened
532 //ie: for collection specific sets - attila dec10-04
533 String set_directory = getGLIMetadataDirectoryPath();
534
535 SetSelectionDialog m = new SetSelectionDialog();
536 m.setVisible(true);
537 // m.show();
538
539 //once we have clicked 'ok' on the jdialog above, then we should have
540 //the directory pointer in string set_directory...and pass it to the jfilechoose constru
541 return;
542 }
543
544 // File -> Save
545 if (event_source == file_save) {
546 msm.save();
547 atLeastOneSetChanged = false;
548 return;
549 }
550
551 // File -> Exit
552 if (event_source == file_exit) {
553 exit(); //The exit() method checks if data needs saving.
554 }
555
556 // File -> Preferences
557 if(event_source == file_preferences){
558 GEMSPreferences GemsPreferences = new GEMSPreferences();
559 }
560
561 // Edit -> Cut
562 if (event_source == edit_cut) {
563 try {
564 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
565 // Get the component with selected text as a JTextComponent
566 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
567 // Cut the text to the clipboard
568 text.cut();
569 }
570 catch (ClassCastException cce) {
571 // If the component is not a text component ignore the cut command
572 DebugStream.println(cce.toString());
573 }
574 return;
575 }
576
577 // Edit -> Copy
578 if (event_source == edit_copy) {
579 try {
580 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
581 // Get the component with selected text as a JTextComponent
582 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();//getFocusOwner();
583 text.copy();
584 }
585 catch (Exception cce) {
586 // If the component is not a text component ignore the copy command
587 DebugStream.println(cce.toString());
588 }
589 return;
590 }
591
592 // Edit -> Paste
593 if (event_source == edit_paste) {
594 try {
595 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
596 // Get the component with selected text as a JTextComponent
597 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
598 // Cut the text to the clipboard
599 text.paste();
600 }
601 catch (ClassCastException cce) {
602 // If the component is not a text component ignore the paste command
603 DebugStream.println(cce.toString());
604 }
605 return;
606 }
607
608 // Help -> Help
609 if (event_source == help_help) {
610 HelpFrame.setView("editingmetadatasets");
611 return;
612 }
613 }
614 }
615
616
617 private class MetadataSetFileFilter
618 extends FileFilter
619 {
620 public boolean accept(File file)
621 {
622 String file_name = file.getName().toLowerCase();
623 return(file_name.endsWith(".mds") || file_name.indexOf(".") == -1);
624 }
625
626 public String getDescription()
627 {
628 return Dictionary.get("MetadataSet.Files");
629 }
630 }
631
632
633 private class ActionTask
634 extends Thread {
635 private int action;
636 public ActionTask(int action) {
637 this.action = action;
638 }
639 public void run() {
640 boolean complete = false;
641 while(!complete) {
642 if(self.isVisible()) {
643 switch(action) {
644 case ADD_SET:
645 add_set_action_listener.actionPerformed(new ActionEvent(this, 0, "Blarg!"));
646 break;
647 case REMOVE_SET:
648 if(!mds_tree.isSelectionEmpty()) {
649 remove_set_action_listener.actionPerformed(new ActionEvent(this, 0, "Blarg!"));
650 }
651 break;
652 }
653 complete = true;
654 }
655 else {
656 try {
657 synchronized(this) {
658 wait(100);
659 }
660 }
661 catch(Exception exception) {
662 }
663 }
664 }
665 }
666 }
667 //callback method
668 protected void processWindowEvent(WindowEvent evt){
669
670 if(evt.getID() == WindowEvent.WINDOW_CLOSING){
671
672 exit();
673 }
674 }
675 //called from MetadataSetManager...I don't think it should be here anymore, but for now it's ok
676
677 public void warn_cant_load_set(){
678 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Already_Loaded_Set_Error"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
679 }
680 public void dispose() {
681
682
683 //if anything has changed, warn user that they should save
684 if(atLeastOneSetChanged == true) {
685
686 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Exit_Save", Dictionary.get("GEMS.Element")), Dictionary.get("GEMS.Confirm_Exit_Save_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
687 // System.out.println("Exit: "+result);
688 if(result == 0) {
689 msm.save();
690 }
691 }
692 atLeastOneSetChanged = false;
693 // Destructor
694 card_layout = null;
695 screen_size = null;
696 self = null;
697 details_pane = null;
698 element_attributes = null;
699 set_attributes = null;
700 set_name = null;
701 mds_tree = null;
702
703 popupListener = null;
704 // Dispose of inner dialogs
705 if (add_element_action_listener != null) {
706 add_element_action_listener.dispose();
707 add_element_action_listener = null;
708 }
709 if (add_or_edit_attribute_action_listener != null) {
710 add_or_edit_attribute_action_listener.dispose();
711 add_or_edit_attribute_action_listener = null;
712 }
713 remove_set_action_listener = null;
714
715 //close
716 super.dispose();
717 }
718
719
720 /**
721 Class to handle adding or modifying element attributes.
722 */
723 private class AddOrEditAttributeActionListener
724 extends ModalDialog
725 implements ActionListener, MouseListener {
726 private boolean add_type = true;
727 private ComboArea value = null;
728 private JButton cancel_button = null;
729 private JButton ok_button = null;
730 private JComboBox language_box = null;
731 private GComboBox name = null;
732 private HashMap name_to_values = null;
733 private JLabel target = null;
734 private JLabel target_label = null;
735 private Vector attributeLists = null;
736
737 org.w3c.dom.Document lang = XMLTools.parseXMLFile(getGLIDirectoryPath() + "classes" + File.separator + "xml" + File.separator + "languages.xml", false);
738
739 /** Constructor. */
740 public AddOrEditAttributeActionListener() {
741 super(self);
742 setModal(true);
743 attributeLists = new Vector();
744 attributeLists.add("identifier");
745 attributeLists.add("comment");
746 attributeLists.add("definition");
747 attributeLists.add("name");
748
749 attributeLists.add("creator");
750 attributeLists.add("date");
751 attributeLists.add("contact");
752 attributeLists.add("family");
753
754 attributeLists.add("lastchanged");
755 attributeLists.add("language_dependant");
756 attributeLists.add("version");
757 attributeLists.add("datatype");
758
759 attributeLists.add("obligation");
760 attributeLists.add("maximum_occurence");
761 attributeLists.add("registration_authority");
762
763 setSize(ADD_OR_EDIT_ATTRIBUTE_SIZE);
764 name_to_values = new HashMap();
765
766 // Creation
767 JPanel content_pane = (JPanel) getContentPane();
768 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
769 JPanel upper_pane = new JPanel();
770 upper_pane.setOpaque(false);
771
772 JPanel labels_pane = new JPanel();
773 JPanel boxes_pane = new JPanel();
774
775 target_label = new JLabel();
776 target_label.setOpaque(false);
777 target = new JLabel();
778 target.setOpaque(false);
779
780 JLabel name_label = new JLabel();
781 name_label.setOpaque(false);
782 Dictionary.setText(name_label, "GEMS.Name");
783 name = new GComboBox();
784 name.setEditable(true);
785 Dictionary.setTooltip(name, "GEMS.Attribute_Name_Tooltip");
786
787 JLabel language_label = new JLabel();
788 language_label.setOpaque(false);
789 Dictionary.setText(language_label, "GEMS.Language");
790 language_box = new JComboBox();
791
792 for(int n = 0; n < attributeLists.size(); n++){
793 name.add(attributeLists.get(n));
794 }
795
796 Dictionary.setTooltip(language_box, "GEMS.Attribute_Language_Tooltip");
797
798 JPanel center_pane = new JPanel();
799 center_pane.setOpaque(false);
800 value = new ComboArea(Dictionary.get("GEMS.Values"), COMPONENT_SIZE);
801 value.setOpaque(false);
802
803 JTextArea v_text_area = (JTextArea) value.getTextComponent();
804 v_text_area.setBackground(config.getColor("coloring.collection_tree_background", false));
805 v_text_area.setForeground(config.getColor("coloring.collection_tree_foreground", false));
806 v_text_area.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
807 v_text_area.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
808 Dictionary.setTooltip(v_text_area, "GEMS.Attribute_Value_Tooltip");
809
810 JPanel button_pane = new JPanel();
811 button_pane.setOpaque(false);
812 ok_button = new GLIButton();
813 ok_button.setMnemonic(KeyEvent.VK_O);
814 getRootPane().setDefaultButton(ok_button);
815 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
816 cancel_button = new GLIButton();
817 cancel_button.setMnemonic(KeyEvent.VK_C);
818 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
819
820 // Connection
821 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
822 cancel_button.addActionListener(this);
823 name.addActionListener(this);
824 ok_button.addActionListener(this);
825 ok_button_enabler.add((JTextComponent)name.getEditor()); // Assuming the default editor is a JTextField!
826
827 // Layout
828 labels_pane.setLayout(new GridLayout(3,1,0,5));
829 labels_pane.add(target_label);
830 labels_pane.add(name_label);
831 labels_pane.add(language_label);
832
833 boxes_pane.setLayout(new GridLayout(3,1,0,5));
834 boxes_pane.add(target);
835 boxes_pane.add(name);
836 boxes_pane.add(language_box);
837
838 upper_pane.setLayout(new BorderLayout(5,0));
839 upper_pane.add(labels_pane, BorderLayout.WEST);
840 upper_pane.add(boxes_pane, BorderLayout.CENTER);
841
842 value.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
843
844 button_pane.setLayout(new GridLayout(1,2,5,0));
845 button_pane.add(ok_button);
846 button_pane.add(cancel_button);
847
848 center_pane.setLayout(new BorderLayout());
849 center_pane.add(value, BorderLayout.CENTER);
850 center_pane.add(button_pane, BorderLayout.SOUTH);
851
852 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
853 content_pane.setLayout(new BorderLayout());
854 content_pane.add(upper_pane, BorderLayout.NORTH);
855 content_pane.add(center_pane, BorderLayout.CENTER);
856
857 setLocation((config.screen_size.width - ADD_OR_EDIT_ATTRIBUTE_SIZE.width) / 2, (config.screen_size.height - ADD_OR_EDIT_ATTRIBUTE_SIZE.height) / 2);
858
859 GEMSLanguageManager GemsLangManager = new GEMSLanguageManager(getGLIDirectoryPath() + "classes" + File.separator + "xml" + File.separator + "languages.xml");
860
861 Vector languagecodes = GemsLangManager.getLanguageCodes();
862
863 for(int p = 0; p < languagecodes.size(); p++){
864
865 language_box.addItem(languagecodes.get(p).toString());
866 }
867
868 String code = Configuration.getLanguage();
869 language_box.setSelectedItem(code);
870 }
871
872 //Handle double clicks in the table.
873 public void mouseClicked(MouseEvent e)
874 {
875 if(e.getSource() == element_attributes || e.getSource() == set_attributes)
876 {
877 if(e.getClickCount() == 2) //Double click
878 {
879 //Show the Edit Attribute dialog
880 this.menuEditValue();
881 this.editAttribute();
882 }
883 }
884 }
885 //These methods are required by interface MouseListener
886 public void mouseEntered(MouseEvent e){}
887 public void mouseExited(MouseEvent e){}
888 public void mousePressed(MouseEvent e){}
889 public void mouseReleased(MouseEvent e){}
890
891 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to add a new attribute to the selected set or element.
892 * @param event An <strong>ActionEvent</strong> containing information about the event.
893 */
894 public void actionPerformed(ActionEvent event) {
895 Object source = event.getSource();
896 AttributeTableModel model = null;
897
898 if(current_element != null)
899 {
900 target.setText(current_element.getName());
901 Dictionary.setText(target_label, "GEMS.Target");
902 }
903 else if(current_set != null)
904 {
905 Dictionary.setText(target_label, "GEMS.Set");
906 target.setText(current_set.toString());
907 Dictionary.setText(target_label, "GEMS.Target");
908 }
909
910 if (source == popupListener.menuEditValue)
911 {
912 this.menuEditValue();
913 }
914
915 if(source == ok_button) {
916 boolean success = true;
917
918 // Add or edit a set/element attribute
919 switch(current_attribute_type) {
920 case GEMSNode.SET:
921 model = (AttributeTableModel) set_attributes.getModel();
922 success = addOrEditSetAttribute(model);
923 break;
924 case GEMSNode.ELEMENT:
925 model = (AttributeTableModel) element_attributes.getModel();
926 success = addOrEditElementAttribute(model);
927 break;
928 }
929
930 if (success) {
931 // Hide dialog
932 atLeastOneSetChanged = true;
933 setVisible(false);
934 return;
935 }
936 else
937 {
938 //If no success (an attribute with that name already exists), do nothing.
939 }
940 }
941 else if(source == cancel_button) {
942 // Hide dialog
943 setVisible(false);
944 return;
945 }
946 else if(source == name) {
947 //System.err.println("source is name");
948 Object object = name.getSelectedItem();
949 if(object != null) {
950 java.util.List values = (java.util.List) name_to_values.get(object.toString());
951
952 if(value != null && values != null){
953 value.clear();
954 for(int i = 0; i < values.size(); i++) {
955 value.add(values.get(i));
956 }
957 }
958 }
959 }
960 else if (source == popupListener.menuAddAttributeAttribute || source == popupListener.menuAddAttributeSet || source == popupListener.menuAddAttributeElement){
961
962 Dictionary.setText(this, "GEMS.Add_Attribute");
963 for(int i = 0; i < attributeLists.size(); i++) {
964 name.add(attributeLists.get(i).toString());
965
966 }
967 name.setEnabled(true);
968 setVisible(true);
969 }
970
971 else if(current_attribute != -1) {
972 this.editAttribute();
973 }
974
975 source = null;
976 }
977
978 private void menuEditValue()
979 {
980 AttributeTableModel tablemodel = null;
981
982 String prevLang = new String("");
983 String prevValue = new String("");
984
985 add_type = false;
986 //grab the table model based on what is currently selected
987 switch(current_attribute_type) {
988 case GEMSNode.SET:
989 tablemodel = (AttributeTableModel) set_attributes.getModel();
990 //grab value in table
991 prevLang = tablemodel.getValueAt(current_attribute,0).toString();
992 prevValue = tablemodel.getValueAt(current_attribute,1).toString();
993
994 break;
995 case GEMSNode.ELEMENT:
996 tablemodel = (AttributeTableModel) element_attributes.getModel();
997 //grab values in table( lang and value)
998 prevLang = tablemodel.getValueAt(current_attribute,1).toString();
999 prevValue = tablemodel.getValueAt(current_attribute,2).toString();
1000
1001 break;
1002 default:
1003 //by default grab element_attr's
1004 tablemodel = (AttributeTableModel) element_attributes.getModel();
1005 prevLang = tablemodel.getValueAt(current_attribute,1).toString();
1006 prevValue = tablemodel.getValueAt(current_attribute,2).toString();
1007
1008 break;
1009 }
1010 language_box.setEnabled(false);
1011
1012 //if a set attr is selected, then do not do any lang operations, other than setting index to -1
1013 if(current_attribute_type != GEMSNode.SET) {
1014
1015 //set the current language to show up in language_box(no lang if no lang specified)
1016 if(prevLang == null || prevLang.compareTo(" ")==0 || prevLang.compareTo("") == 0 || prevLang.compareTo(" ")==0) {
1017 language_box.setSelectedIndex(-1);
1018
1019 }
1020 else {
1021 language_box.setSelectedItem(prevLang.toLowerCase());
1022 }
1023 }// end currattr != GEMSnode.set
1024 else {
1025
1026 language_box.setSelectedIndex(-1);
1027
1028 }// end currattr == GEMSnode.set
1029 value.setText(prevValue);
1030 }
1031
1032 private void editAttribute()
1033 {
1034 //System.err.println("just entered editAttribute"); //debug
1035 AttributeTableModel model = null;
1036 Dictionary.setText(this, "GEMS.Edit_Attribute");
1037
1038 switch(current_attribute_type) {
1039 case GEMSNode.ELEMENT:
1040 model = (AttributeTableModel) element_attributes.getModel();
1041 break;
1042 case GEMSNode.SET:
1043 model = (AttributeTableModel) set_attributes.getModel();
1044 break;
1045 }
1046 add_type = false;
1047 String name_str = (String) model.getValueAt(current_attribute, 0);
1048 String value_str = (String) model.getValueAt(current_attribute, model.getColumnCount() - 1);
1049 model = null;
1050 // Retrieve the appropriate value model
1051 java.util.List values = (java.util.List) name_to_values.get(name_str);
1052 // Only possible for collection file selections.
1053 if(values == null) {
1054 values = msm.getElements();
1055 }
1056 name.setSelectedItem(name_str);
1057 name_str = null;
1058 for(int i = 0; i < values.size(); i++) {
1059 Object temp_value = values.get(i);
1060 if(temp_value instanceof ElementWrapper) {
1061 value.add(new NameElementWrapperEntry(temp_value));
1062 }
1063 else {
1064 value.add(temp_value);
1065 }
1066 }
1067 values = null;
1068 value.setSelectedItem(value_str);
1069 value_str = null;
1070 setVisible(true);
1071 }
1072
1073 private boolean addOrEditSetAttribute(AttributeTableModel model)
1074 {
1075 String new_name_str = name.getSelectedItem().toString();
1076 String value_str = Codec.transform(Codec.transformUnicode(value.getText()), Codec.TEXT_TO_DOM);
1077 String language_code = (String) language_box.getSelectedItem();
1078 String old_name_str = null;
1079 boolean cont = false;
1080 boolean edit = false;
1081
1082 if(!add_type && current_attribute != -1) //If edit, grab the attribute's old name
1083 {
1084 old_name_str = (String) set_attributes.getValueAt(current_attribute, 0);
1085 edit = true;
1086 }
1087
1088 // Check that there isn't already an entry for this attribute
1089 if (!model.contains(new_name_str, language_code) || (edit && new_name_str.equals(old_name_str)))
1090 {
1091 if(edit) //If edit, remove old attribute
1092 {
1093 current_set.removeAttribute(old_name_str);
1094 model.removeRow(current_attribute);
1095 }
1096
1097 // Add the new attribute
1098 current_set.addAttribute(new_name_str, value_str);
1099 // Update the attribute table
1100 model.add(new Attribute(new_name_str, value_str));
1101 cont = true;
1102 }
1103 // Otherwise show an error message and do not proceed
1104 else
1105 {
1106 cont = false;
1107 JOptionPane.showMessageDialog(self,
1108 Dictionary.get("GEMS.Attribute_Already_Exists"),
1109 Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1110 }
1111
1112 value_str = null;
1113 new_name_str = null;
1114 return cont;
1115 }
1116
1117
1118 private boolean addOrEditElementAttribute(AttributeTableModel model)
1119 {
1120 String new_name_str = name.getSelectedItem().toString();
1121 String old_name_str = null;
1122 String language_code = (String) language_box.getSelectedItem();
1123 String value_str = Codec.transform(Codec.transformUnicode(value.getText()), Codec.TEXT_TO_DOM);
1124 String old_value_str = null;
1125 String old_lang_code = null;
1126 boolean cont = false;
1127 boolean edit = false;
1128
1129 if(!add_type && current_attribute != -1) //An edit
1130 {
1131 Attribute old_attribute = model.getAttribute(current_attribute);
1132 old_value_str = old_attribute.value;
1133 old_lang_code = old_attribute.language;
1134 old_name_str = (String) element_attributes.getValueAt(current_attribute, 0); //get the old name.
1135 edit = true;
1136 }
1137
1138 //Check that there isn't already an entry for this attribute
1139 if (!model.contains(new_name_str, language_code) || (edit && new_name_str.equals(old_name_str)))
1140 {
1141 if(edit) //If this is an edit, remove the old attribute
1142 {
1143 current_element.removeAttribute(old_name_str, old_lang_code, old_value_str);
1144 model.removeRow(current_attribute);
1145 }
1146
1147 // Add the new attribute
1148 //System.err.println("current_element is: " + current_element.toString()); //debug
1149 current_element.addAttribute(new_name_str, language_code, value_str);
1150 // Update the attribute table
1151 int row = model.add(new Attribute(new_name_str, language_code, value_str));
1152 element_attributes.setRowSelectionInterval(row, row);
1153 cont = true;
1154 }
1155 // Otherwise show an error message and do not proceed
1156 else
1157 {
1158 cont = false;
1159 JOptionPane.showMessageDialog(self,
1160 Dictionary.get("GEMS.Attribute_Already_Exists"),
1161 Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1162 }
1163
1164 value_str = null;
1165 language_code = null;
1166 new_name_str = null;
1167 return cont;
1168 }
1169 }
1170
1171
1172 private class AddSubelementActionListener extends AddElementActionListener implements ActionListener {
1173
1174 public AddSubelementActionListener() {
1175 Dictionary.setText(this, "GEMS.Add_Subelement");
1176 Dictionary.setTooltip(name_field, "GEMS.Subelement_Name_Tooltip");
1177 }
1178
1179 public void actionPerformed(ActionEvent event)
1180 {
1181 Object source = event.getSource();
1182 current_element = current_node.getElement(); //current_element here is used generically for a element or subelement.
1183
1184 if(source == ok_button) //Add then dispose
1185 {
1186 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1187 current_set = msm.getSet(current_element.getNamespace());
1188 if(current_set != null)
1189 {
1190 // If this subelement doesn't already exist.
1191 if(!current_element.containsSubelement(name_str))
1192 {
1193 // Add it,
1194 String language_code = config.getLanguage();
1195 ElementWrapper subelement = current_set.addElement(name_str, language_code, current_node);
1196
1197 final GEMSNode new_node = model.add(current_node, subelement, GEMSNode.ELEMENT); //Then update the tree.
1198
1199 //SwingUtilities.invokeLater is used so that expandPath works on new parents.
1200 SwingUtilities.invokeLater(new Runnable() {
1201 public void run() {
1202 mds_tree.expandPath(new TreePath(current_node.getPath())); //Expand element so can see subelement.
1203 mds_tree.getSelectionModel().setSelectionPath(new TreePath(new_node)); //works, but node on tree doesn't look hilighted!
1204 }
1205 });
1206
1207 //Done. Finish up.
1208 subelement = null;
1209 setVisible(false);
1210 atLeastOneSetChanged = true; //mark as changed
1211 }
1212 else
1213 {
1214 //A subelement with the same name exists. Display an error message.
1215 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Subelement_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1216 }
1217 }
1218 else
1219 {
1220 //This should not happen.
1221 System.err.println("Error: current_set is null in AddSubelementActionListener");
1222 }
1223 }
1224 else if(source == cancel_button)
1225 {
1226 setVisible(false);
1227 }
1228 else
1229 {
1230 set_field.setText(current_node.toString()); //set to the name of the subelement
1231 name_field.setText("");
1232 setVisible(true);
1233 }
1234 }
1235
1236 public void dispose()
1237 {
1238 cancel_button = null;
1239 ok_button = null;
1240 name_field = null;
1241 set_field = null;
1242 super.dispose();
1243 }
1244 }
1245
1246
1247 private class AddElementActionListener
1248 extends ModalDialog
1249 implements ActionListener {
1250 protected JButton cancel_button = null;
1251 protected JButton ok_button = null;
1252 protected JLabel set_field = null;
1253 protected NonWhitespaceField name_field = null;
1254 public AddElementActionListener() {
1255 super(self);
1256 setModal(true);
1257 setSize(ADD_ELEMENT_SIZE);
1258 // Creation
1259 JPanel content_pane = (JPanel) getContentPane();
1260 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1261 JPanel center_pane = new JPanel();
1262 center_pane.setOpaque(false);
1263 Dictionary.setText(this, "GEMS.Add_Element");
1264
1265 JPanel labels_pane = new JPanel();
1266 labels_pane.setOpaque(false);
1267 JLabel set_label = new JLabel();
1268 set_label.setOpaque(false);
1269 Dictionary.setText(set_label, "GEMS.Set");
1270 set_field = new JLabel();
1271 set_field.setOpaque(false);
1272
1273 JPanel values_pane = new JPanel();
1274 values_pane.setOpaque(false);
1275 JLabel name_label = new JLabel();
1276 name_label.setOpaque(false);
1277 Dictionary.setText(name_label, "GEMS.Name");
1278 name_field = new NonWhitespaceField();
1279 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1280 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1281 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1282 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1283 Dictionary.setTooltip(name_field, "GEMS.Element_Name_Tooltip");
1284
1285 JPanel button_pane = new JPanel();
1286 button_pane.setOpaque(false);
1287
1288 ok_button = new GLIButton();
1289 ok_button.setMnemonic(KeyEvent.VK_O);
1290 getRootPane().setDefaultButton(ok_button);
1291 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1292 cancel_button = new GLIButton();
1293 cancel_button.setMnemonic(KeyEvent.VK_C);
1294 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1295
1296 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
1297
1298 // Connection
1299 cancel_button.addActionListener(this);
1300 ok_button.addActionListener(this);
1301 ok_button_enabler.add(name_field);
1302
1303 // Layout
1304 labels_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
1305 labels_pane.setLayout(new GridLayout(2,1));
1306 labels_pane.add(set_label);
1307 labels_pane.add(name_label);
1308
1309 values_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
1310 values_pane.setLayout(new GridLayout(2,1));
1311 values_pane.add(set_field);
1312 values_pane.add(name_field);
1313
1314 center_pane.setLayout(new BorderLayout(5,5));
1315 center_pane.add(labels_pane, BorderLayout.WEST);
1316 center_pane.add(values_pane, BorderLayout.CENTER);
1317
1318 button_pane.setLayout(new GridLayout(1,2,0,5));
1319 button_pane.add(ok_button);
1320 button_pane.add(cancel_button);
1321
1322 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1323 content_pane.setLayout(new BorderLayout());
1324 content_pane.add(center_pane, BorderLayout.CENTER);
1325 content_pane.add(button_pane, BorderLayout.SOUTH);
1326
1327 setLocation((config.screen_size.width - ADD_ELEMENT_SIZE.width) / 2, (config.screen_size.height - ADD_ELEMENT_SIZE.height) / 2);
1328 }
1329
1330 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1331 * @param event An <strong>ActionEvent</strong> containing information about the event.
1332 */
1333 public void actionPerformed(ActionEvent event) {
1334 Object source = event.getSource();
1335 if(source == ok_button) {
1336 // Add then dispose
1337 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1338 // If this element doesn't already exist.
1339 if(!current_set.containsElement(name_str)) {
1340 // Add it,
1341 String language_code = config.getLanguage();
1342 ElementWrapper element = current_set.addElement(name_str, language_code, null);
1343
1344 // Then update the tree
1345 model.add(current_node, element, GEMSNode.ELEMENT);
1346 //SwingUtilities.invokeLater is used so that expandPath works on new parents.
1347 SwingUtilities.invokeLater(new Runnable() {
1348 public void run() {
1349 mds_tree.expandPath(new TreePath(current_node.getPath())); //expand set.
1350 }
1351 });
1352
1353 // Done
1354 element = null;
1355 setVisible(false);
1356
1357 //mark as changed
1358 atLeastOneSetChanged = true;
1359 current_set.setSetChanged(true);
1360
1361 }
1362 // Otherwise show an error message and do not proceed.
1363 else {
1364 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Element_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1365 }
1366 name_str = null;
1367 }
1368 else if(source == cancel_button) {
1369 // Dispose
1370 setVisible(false);
1371 }
1372 else {
1373 if(current_set != null) { //Does this ever happen? --Matthew
1374 // You can't manually add elements to the Greenstone metadata set.
1375 if(!current_set.getNamespace().equals("")) {
1376 set_field.setText(current_set.toString());
1377 name_field.setText("");
1378 // Display
1379 setVisible(true);
1380 }
1381 // Warn the user that they can't do that dave.
1382 else {
1383
1384 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Cannot_Add_Elements_To_Greenstone_MDS"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1385 }
1386 }
1387 }
1388 source = null;
1389 }
1390
1391 public void dispose() {
1392 cancel_button = null;
1393 ok_button = null;
1394 name_field = null;
1395 set_field = null;
1396 super.dispose();
1397 }
1398 }
1399
1400
1401 private class AddSetActionListener
1402 extends ModalDialog
1403 implements ActionListener {
1404 private JButton cancel_button = null;
1405 private JButton ok_button = null;
1406 private JTextField name_field = null;
1407 private JTextField namespace_field = null;
1408 private JComboBox existingSetJComboBox = new JComboBox();
1409
1410 public AddSetActionListener() {
1411 super(self);
1412 setModal(true);
1413 setSize(ADD_SET_SIZE);
1414 Dictionary.setText(this, "GEMS.Add_Set");
1415
1416 // Creation
1417 JPanel content_pane = (JPanel) getContentPane();
1418 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1419 JPanel center_pane = new JPanel();
1420 center_pane.setOpaque(false);
1421
1422 JPanel label_pane = new JPanel();
1423 JPanel boxes_pane = new JPanel();
1424
1425 JLabel namespace_label = new JLabel();
1426 namespace_label.setOpaque(false);
1427 Dictionary.setText(namespace_label, "GEMS.Namespace");
1428 namespace_field = TransformCharacterTextField.createNamespaceTextField();
1429 namespace_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1430 namespace_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1431 namespace_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1432 namespace_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1433 Dictionary.setTooltip(namespace_field, "GEMS.Set_Namespace_Tooltip");
1434
1435 JLabel name_label = new JLabel();
1436 name_label.setOpaque(false);
1437 Dictionary.setText(name_label, "GEMS.Name");
1438 name_field = new JTextField();
1439 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1440 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1441 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1442 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1443 Dictionary.setTooltip(name_field, "GEMS.Set_Name_Tooltip");
1444
1445 JPanel button_pane = new JPanel();
1446 button_pane.setOpaque(false);
1447
1448 ok_button = new GLIButton();
1449 ok_button.setMnemonic(KeyEvent.VK_O);
1450 getRootPane().setDefaultButton(ok_button);
1451 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1452 cancel_button = new GLIButton();
1453 cancel_button.setMnemonic(KeyEvent.VK_C);
1454 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1455 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
1456
1457 // Connection
1458 cancel_button.addActionListener(this);
1459 ok_button.addActionListener(this);
1460 ok_button_enabler.add(name_field);
1461 ok_button_enabler.add(namespace_field);
1462
1463 // Layout
1464 label_pane.setLayout(new GridLayout(3,1));
1465 label_pane.add(name_label);
1466 label_pane.add(namespace_label);
1467 boxes_pane.setLayout(new GridLayout(3,1));
1468 boxes_pane.add(name_field);
1469 boxes_pane.add(namespace_field);
1470
1471 JLabel inheritJLabel = new JLabel();
1472 Dictionary.setText(inheritJLabel, "GEMS.inheritMetadataSet");
1473
1474 label_pane.add(inheritJLabel);
1475
1476 int getSetsLen = msm.getSets().toArray().length;
1477 Vector theSets = msm.getSets();
1478
1479 for(int k = 0; k < theSets.size(); k++){
1480 MetadataSet ms = (MetadataSet)theSets.elementAt(k);
1481
1482 existingSetJComboBox.addItem(new String(ms.getName() + " #% " + ms.getFile().toString()));
1483
1484 }
1485 //add sets to existingSetJComboBox
1486
1487 JLabel dummyl = new JLabel();
1488 Dictionary.setText(dummyl, "GEMS.Add_Set.No_Inherit");
1489
1490 existingSetJComboBox.addItem("Do not inherit");
1491 existingSetJComboBox.setSelectedIndex(getSetsLen);
1492 boxes_pane.add(existingSetJComboBox);
1493
1494 center_pane.setLayout(new BorderLayout(5,0));
1495 center_pane.add(label_pane, BorderLayout.WEST);
1496 center_pane.add(boxes_pane, BorderLayout.CENTER);
1497
1498 button_pane.setLayout(new GridLayout(1,2,0,5));
1499 button_pane.add(ok_button);
1500 button_pane.add(cancel_button);
1501
1502 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1503 content_pane.setLayout(new BorderLayout());
1504 content_pane.add(center_pane, BorderLayout.CENTER);
1505 content_pane.add(button_pane, BorderLayout.SOUTH);
1506
1507 setLocation((config.screen_size.width - ADD_SET_SIZE.width) / 2, (config.screen_size.height - ADD_SET_SIZE.height) / 2);
1508 }
1509
1510 private boolean a_set_exists_with_this_namespace(String namespace){
1511 Vector p = msm.getSets();
1512 boolean flag = false;
1513 for(int k = 0; k < p.size(); k++){
1514 MetadataSet s = (MetadataSet)p.get(k);
1515
1516 if(s.getNamespace().compareTo(namespace) == 0){
1517 flag = true;
1518 }
1519 }
1520
1521 return flag;
1522 }
1523
1524
1525 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1526 * @param event An <strong>ActionEvent</strong> containing information about the event.
1527 */
1528 public void actionPerformed(ActionEvent event) {
1529 Object source = event.getSource();
1530
1531 if(source == ok_button) {
1532 //this code below handles whether we inherit from an existing set or not
1533
1534 String namespace_str = namespace_field.getText();
1535 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1536
1537 if (existingSetJComboBox.getSelectedItem().toString().trim().compareTo("Do not inherit") == 0){
1538
1539 // Ensure the set doesn't already exist
1540 if(a_set_exists_with_this_namespace(namespace_str) == false){
1541
1542 MetadataSet set = msm.addSet(namespace_str, name_str);
1543
1544 //mark as set changed = true
1545 set.setSetChanged(true);
1546 atLeastOneSetChanged = true;
1547
1548 // Update tree.
1549 model.add(null, set, GEMSNode.SET);
1550 // Done
1551 set = null;
1552 setVisible(false);
1553
1554 }
1555 else{
1556 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Set_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1557 }
1558
1559 name_str = null;
1560 namespace_str = null;
1561 }//end do not inherit
1562 else {
1563 //Should change this to use XML parsing utilites --Matthew
1564 //lets grab the metadata we want to inherit from...
1565 String anitem = existingSetJComboBox.getSelectedItem().toString();
1566
1567 if(a_set_exists_with_this_namespace(namespace_field.getText()) == false){
1568 //setup to read the filename from mds file
1569 String [] items = anitem.split("#%");
1570 try {
1571 FileInputStream fstream = new FileInputStream(items[1].trim());
1572 BufferedReader in = new BufferedReader(new InputStreamReader(fstream, "UTF8"));
1573
1574 FileOutputStream out;
1575 PrintWriter p;
1576 //setup to write to filename from existing file
1577 try {
1578 out = new FileOutputStream(getGLIMetadataDirectoryPath() + namespace_str + ".mds");
1579 OutputStreamWriter pout = new OutputStreamWriter(out, "UTF8");
1580 p = new PrintWriter(pout);
1581
1582 while(in.ready()){
1583 String nextline = in.readLine();
1584
1585 if(nextline.matches(".+namespace=\".+\".*") == true) {
1586 nextline = nextline.replaceFirst("namespace=\".+\"","namespace=\"" + namespace_str+ "\"");
1587 }
1588 else {
1589 nextline = nextline.replaceFirst(">.+</Name>",">" + name_str + "</Name>");
1590 }
1591 p.print(nextline + "\n");
1592 }
1593 p.close();
1594
1595 MetadataSet loadedset = msm.loadMetadataSet(new File(getGLIMetadataDirectoryPath() + namespace_str + ".mds"));
1596 model.add(null, loadedset, GEMSNode.SET);
1597 }
1598 catch(Exception e){
1599 System.out.println("Print file error");
1600 }
1601 }
1602 catch(Exception e){
1603 System.out.println("File Input error");
1604 }
1605
1606 }//msm.getset(namespacE) == null
1607 else{
1608 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Set_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1609 }
1610 setVisible(false);
1611 }
1612 } //if(source == ok_button)
1613 else if(source == cancel_button) {
1614 setVisible(false);
1615 }
1616 else {
1617 name_field.setText("");
1618 setVisible(true);
1619 }
1620 } //actionPerformed
1621
1622 public void dispose() {
1623 cancel_button = null;
1624 ok_button = null;
1625 name_field = null;
1626 super.dispose();
1627 }
1628 }
1629
1630 ////
1631 private class SetSelectionDialog
1632 extends ModalDialog
1633 implements ActionListener {
1634 private JButton cancel_button = null;
1635 private JButton ok_button = null;
1636 private JComboBox existingSetJComboBox = new JComboBox();
1637
1638 public SetSelectionDialog() {
1639 super(self);
1640 setModal(true);
1641 setSize(OPEN_SETS_SIZE);
1642 Dictionary.setText(this, "GEMS.Open_Set");
1643
1644 // Creation
1645 JPanel content_pane = (JPanel) getContentPane();
1646 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1647 JPanel center_pane = new JPanel();
1648 center_pane.setOpaque(false);
1649
1650 JPanel boxes_pane = new JPanel();
1651
1652 JPanel button_pane = new JPanel();
1653 button_pane.setOpaque(false);
1654
1655 ok_button = new GLIButton();
1656 ok_button.setMnemonic(KeyEvent.VK_O);
1657 getRootPane().setDefaultButton(ok_button);
1658 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1659 cancel_button = new GLIButton();
1660 cancel_button.setMnemonic(KeyEvent.VK_C);
1661 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1662
1663 // Connection
1664 cancel_button.addActionListener(this);
1665 ok_button.addActionListener(this);
1666
1667 // Layout
1668 boxes_pane.setLayout(new GridLayout(4,1));
1669
1670 JLabel inheritJLabel = new JLabel();
1671 Dictionary.setText(inheritJLabel, "GEMS.inheritMetadataSet");
1672
1673 File[] col_dir = new File(Configuration.gsdl_path + File.separator + "collect").listFiles();
1674
1675 existingSetJComboBox.addItem("Default Metadata Sets #% " + getGLIMetadataDirectoryPath());
1676
1677 for(int k = 0; k < col_dir.length; k++){
1678 if(col_dir[k].isDirectory() && col_dir[k].getName().compareTo("CVS") != 0) {
1679
1680 File metadir = new File(col_dir[k].toString() + File.separator + "metadata");
1681 if(metadir.exists())
1682 existingSetJComboBox.addItem(new String(col_dir[k].getName() + " Collection Sets #% " + col_dir[k].toString() + File.separator + "metadata"));
1683
1684 }
1685
1686 }
1687 //add sets to existingSetJComboBox
1688
1689 existingSetJComboBox.setSelectedIndex(0);
1690 JLabel dummyl = new JLabel();
1691 Dictionary.setText(dummyl, "GEMS.Add_Set.No_Inherit");
1692
1693 boxes_pane.add(new JLabel("Select which group of metadata sets you wish to edit:\n\n\n\n"));
1694 boxes_pane.add(new JLabel("\n"));
1695 boxes_pane.add(existingSetJComboBox);
1696 boxes_pane.add(new JLabel("\n"));
1697
1698 button_pane.setLayout(new GridLayout(1,3,0,5));
1699 button_pane.add(ok_button);
1700 button_pane.add(cancel_button);
1701
1702 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1703 content_pane.setLayout(new BorderLayout());
1704 content_pane.add(boxes_pane, BorderLayout.CENTER);
1705 content_pane.add(button_pane, BorderLayout.SOUTH);
1706
1707 setLocation((config.screen_size.width - ADD_SET_SIZE.width) / 2, (config.screen_size.height - ADD_SET_SIZE.height) / 2);
1708 }
1709 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1710 * @param event An <strong>ActionEvent</strong> containing information about the event.
1711 */
1712
1713 public void actionPerformed(ActionEvent event) {
1714 Object source = event.getSource();
1715
1716 if(source == ok_button) {
1717 //this code below handles whether we inherit from an existing set or not
1718
1719 // String namespace_str = namespace_field.getText();
1720 //String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1721 String loc = (String) existingSetJComboBox.getSelectedItem();
1722
1723 String [] whereto = loc.split("#%");
1724 String set_directory = whereto[1].trim();
1725
1726 //load the jfilechooser:
1727
1728 JFileChooser metadata_set_file_chooser = new JFileChooser(new File(set_directory));
1729 metadata_set_file_chooser.setFileFilter(new MetadataSetFileFilter());
1730 if (metadata_set_file_chooser.showDialog(this, Dictionary.get("General.Open")) == JFileChooser.APPROVE_OPTION) {
1731 MetadataSet metadata_set = msm.loadMetadataSet(metadata_set_file_chooser.getSelectedFile());
1732 // Update tree
1733 //only update tree if the metadata_set return is not null(it will be null if set is already
1734 //opened-Attila - oct 19 0 4
1735 if(metadata_set != null) {
1736 model.add(null, metadata_set, GEMSNode.SET);
1737 }
1738 }
1739
1740
1741 setVisible(false);
1742 }
1743 else if(source == cancel_button) {
1744 setVisible(false);
1745 }
1746 else {
1747 setVisible(true);
1748 }
1749 }
1750
1751 public void dispose() {
1752 cancel_button = null;
1753 ok_button = null;
1754 super.dispose();
1755 }
1756 }
1757
1758 /*
1759 Class to handle removing set or element attributes.
1760 */
1761 private class RemoveAttributeActionListener
1762 implements ActionListener, KeyListener {
1763
1764 /**
1765 Any implementation of KeyListener must include these mothods.
1766 When the DELETE key is pressed, fire the actionPerformed event.
1767 @param e A <strong>KeyEvent</strong> containing information about the event.
1768 */
1769 public void keyTyped(KeyEvent e){
1770 //Do nothing
1771 }
1772 public void keyPressed(KeyEvent e)
1773 {
1774 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_DELETE)
1775 {
1776 //DELETE key pressed
1777 actionPerformed((ActionEvent)null); //is there a better way?
1778 }
1779 }
1780 public void keyReleased(KeyEvent e) {
1781 //Do nothing
1782 }
1783
1784 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1785 * @param event An <strong>ActionEvent</strong> containing information about the event.
1786 */
1787 public void actionPerformed(ActionEvent event) {
1788 if(current_attribute != -1) {
1789 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Removal", Dictionary.get("GEMS.Attribute")), Dictionary.get("GEMS.Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
1790 // Remove this attribute
1791 if(result == 0) {
1792 ignore = true;
1793 //Attributes are tricky little beasties, as they can come from several different places and depend upon what other little beasties have been selected
1794 //Has an element been selected
1795 if(current_element != null) {
1796 // Remove element attribute
1797 String name = (String) element_attributes.getValueAt(current_attribute, 0);
1798 String language = (String) element_attributes.getValueAt(current_attribute, 1);
1799 String value = (String) element_attributes.getValueAt(current_attribute, 2);
1800 current_element.removeAttribute(name, language, value);
1801
1802 // Refresh table
1803 ((AttributeTableModel)element_attributes.getModel()).removeRow(current_attribute);
1804 }
1805 else if(current_set != null) {
1806 String name = (String) set_attributes.getValueAt(current_attribute, 0);
1807 // Remove set attribute
1808 current_set.removeAttribute(name);
1809 // Refresh table
1810 ((AttributeTableModel)set_attributes.getModel()).removeRow(current_attribute);
1811 }
1812 ignore = false;
1813 atLeastOneSetChanged= true;
1814 }
1815 }
1816 else
1817 {
1818 System.err.println("Tried to remove attribute, but current_attribute == -1!"); //This should not happen
1819 }
1820 }
1821 }
1822
1823 /*
1824 Class to handle deletion of elements (including subelements).
1825
1826 Last modified 2/02/05 by Matthew Whyte
1827 */
1828 private class RemoveElementActionListener
1829 implements ActionListener {
1830
1831 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to provide an editing prompt.
1832 * @param event An <strong>ActionEvent</strong> containing information about the event.
1833 */
1834 public void actionPerformed(ActionEvent event) {
1835
1836 if(current_element != null) {
1837 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Removal", Dictionary.get("GEMS.Element")), Dictionary.get("GEMS.Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
1838 // Remove this attribute
1839 if(result == 0) {
1840 //Get the parent element
1841 GEMSNode parent_node = (GEMSNode)current_node.getParent();
1842 ElementWrapper parent_wrapped = parent_node.getElement();
1843
1844 ignore = true;
1845 msm.removeElement(current_element, parent_wrapped);
1846 // Clear selection
1847 mds_tree.clearSelection();
1848 model.remove(current_node);
1849
1850 // Show a blank panel.
1851 card_layout.show(details_pane, BLANK);
1852 ignore = false;
1853
1854 atLeastOneSetChanged = true;
1855 }
1856 }
1857 else {
1858 System.err.println("No element currently selected."); //This should not happen!
1859 }
1860 }
1861 }
1862
1863
1864 /**
1865 Class to handle renaming of a set and/or it's namespace.
1866
1867 @author: Matthew Whyte
1868 Date last modified: 10/01/05
1869 */
1870 private class RenameSetActionListener extends ModalDialog implements ActionListener {
1871
1872 private JButton cancel_button = null;
1873 private JButton ok_button = null;
1874 private JTextField name_field = null;
1875 private JTextField namespace_field = null;
1876
1877 public RenameSetActionListener() {
1878 super(self);
1879 setModal(true);
1880 setSize(RENAME_SET_SIZE);
1881 Dictionary.setText(this, "GEMS.Rename_Set");
1882
1883 // Creation
1884 JPanel content_pane = (JPanel) getContentPane();
1885 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1886 JPanel center_pane = new JPanel();
1887 center_pane.setOpaque(false);
1888
1889 JPanel label_pane = new JPanel();
1890 JPanel boxes_pane = new JPanel();
1891
1892 JLabel namespace_label = new JLabel();
1893 namespace_label.setOpaque(false);
1894 Dictionary.setText(namespace_label, "GEMS.Namespace");
1895 namespace_field = TransformCharacterTextField.createNamespaceTextField();
1896 namespace_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1897 namespace_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1898 namespace_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1899 namespace_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1900 Dictionary.setTooltip(namespace_field, "GEMS.Rename_Namespace_Tooltip");
1901
1902 JLabel name_label = new JLabel();
1903 name_label.setOpaque(false);
1904 Dictionary.setText(name_label, "GEMS.Name");
1905 name_field = new JTextField();
1906 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1907 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1908 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1909 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1910 Dictionary.setTooltip(name_field, "GEMS.Rename_Name_Tooltip");
1911
1912 JPanel button_pane = new JPanel();
1913 button_pane.setOpaque(false);
1914
1915 ok_button = new GLIButton();
1916 ok_button.setMnemonic(KeyEvent.VK_O);
1917 getRootPane().setDefaultButton(ok_button);
1918 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1919 cancel_button = new GLIButton();
1920 cancel_button.setMnemonic(KeyEvent.VK_C);
1921 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1922 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
1923
1924 // Connection
1925 cancel_button.addActionListener(this);
1926 ok_button.addActionListener(this);
1927 ok_button_enabler.add(name_field);
1928 ok_button_enabler.add(namespace_field);
1929
1930 // Layout
1931 label_pane.setLayout(new GridLayout(2,1));
1932 label_pane.add(name_label);
1933 label_pane.add(namespace_label);
1934 boxes_pane.setLayout(new GridLayout(2,1));
1935 boxes_pane.add(name_field);
1936 boxes_pane.add(namespace_field);
1937
1938 center_pane.setLayout(new BorderLayout(5,0));
1939 center_pane.add(label_pane, BorderLayout.WEST);
1940 center_pane.add(boxes_pane, BorderLayout.CENTER);
1941
1942 button_pane.setLayout(new GridLayout(1,2,0,5));
1943 button_pane.add(ok_button);
1944 button_pane.add(cancel_button);
1945
1946 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1947 content_pane.setLayout(new BorderLayout());
1948 content_pane.add(center_pane, BorderLayout.CENTER);
1949 content_pane.add(button_pane, BorderLayout.SOUTH);
1950
1951 setLocation((config.screen_size.width - RENAME_SET_SIZE.width) / 2, (config.screen_size.height - RENAME_SET_SIZE.height) / 2);
1952 }
1953
1954 private boolean a_set_exists_with_this_namespace(String namespace){
1955 Vector p = msm.getSets();
1956 boolean flag = false;
1957 for(int k = 0; k < p.size(); k++){
1958 MetadataSet s = (MetadataSet)p.get(k);
1959
1960 if(s.getNamespace().compareTo(namespace) == 0){
1961 flag = true;
1962 }
1963 }
1964 return flag;
1965 }
1966
1967
1968 /**
1969 Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component,
1970 allowing us to
1971 * @param event An <strong>ActionEvent</strong> containing information about the event.
1972 */
1973 public void actionPerformed(ActionEvent event) {
1974 Object source = event.getSource();
1975
1976 if(source == ok_button)
1977 {
1978 String namespace_str = namespace_field.getText();
1979 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1980 //Note: The name in name_str is language dependent. However, currently GEMS does not create new sets with different names for different languages(?).
1981 String current_set_namespace = current_set.getNamespace();
1982
1983 //Ensure that the namespace is unique.
1984 if(!(a_set_exists_with_this_namespace(namespace_str)) || (namespace_str.equals(current_set_namespace)))
1985 {
1986 //Hide the set that are about to rename
1987 mds_tree.clearSelection();
1988 model.remove(current_node);
1989
1990 //Rename set & namespace
1991 msm.renameSet(current_set, namespace_str, name_str);
1992 //Add (renamed) set back to tree
1993 model.add(null, current_set, GEMSNode.SET);
1994
1995 //Clean up
1996 card_layout.show(details_pane, BLANK); // Show a blank panel.
1997 ignore = false;
1998 atLeastOneSetChanged = true;
1999 setVisible(false);
2000 }
2001
2002 // Otherwise show an error message and do not proceed.
2003 else
2004 {
2005 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Set_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
2006 }
2007 name_str = null;
2008
2009 }
2010
2011 else if(source == cancel_button)
2012 {
2013 setVisible(false); //hide dialog
2014 }
2015 else
2016 {
2017 name_field.setText(current_set.getName());
2018 namespace_field.setText(current_set.getNamespace());
2019 setVisible(true); //Show the dialog
2020 }
2021 source = null;
2022 }
2023
2024 public void dispose() {
2025 cancel_button = null;
2026 ok_button = null;
2027 name_field = null;
2028 super.dispose();
2029 }
2030 }
2031
2032
2033
2034 /**
2035 Class to handle renaming of an element.
2036
2037 @author: Matthew Whyte
2038 Date last modified: 10/01/05
2039 */
2040 private class RenameElementActionListener extends ModalDialog implements ActionListener {
2041
2042 protected JButton cancel_button = null;
2043 protected JButton ok_button = null;
2044 //private JLabel label = null;
2045 protected NonWhitespaceField name_field = null;
2046
2047 public RenameElementActionListener() {
2048 super(self);
2049 setModal(true);
2050 setSize(RENAME_ELEMENT_SIZE);
2051 // Creation
2052 JPanel content_pane = (JPanel) getContentPane();
2053 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
2054 JPanel center_pane = new JPanel();
2055 center_pane.setOpaque(false);
2056
2057 JPanel labels_pane = new JPanel();
2058 labels_pane.setOpaque(false);
2059
2060 JPanel values_pane = new JPanel();
2061 values_pane.setOpaque(false);
2062 JLabel name_label = new JLabel();
2063 name_label.setOpaque(false);
2064 Dictionary.setText(name_label, "GEMS.New_Name");
2065 name_field = new NonWhitespaceField();
2066 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
2067 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
2068 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
2069 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
2070 Dictionary.setTooltip(name_field, "GEMS.Rename_Element_Tooltip");
2071
2072 JPanel button_pane = new JPanel();
2073 button_pane.setOpaque(false);
2074
2075 ok_button = new GLIButton();
2076 ok_button.setMnemonic(KeyEvent.VK_O);
2077 getRootPane().setDefaultButton(ok_button);
2078 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
2079 cancel_button = new GLIButton();
2080 cancel_button.setMnemonic(KeyEvent.VK_C);
2081 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
2082
2083 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
2084
2085 Dictionary.setText(this, "GEMS.Rename_Element");
2086
2087 // Connection
2088 cancel_button.addActionListener(this);
2089 ok_button.addActionListener(this);
2090 ok_button_enabler.add(name_field);
2091
2092 // Layout
2093 labels_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
2094 labels_pane.setLayout(new GridLayout(1,1));
2095 //labels_pane.add(set_label);
2096 labels_pane.add(name_label);
2097
2098 values_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
2099 values_pane.setLayout(new GridLayout(1,1));
2100 //values_pane.add(label);
2101 values_pane.add(name_field);
2102
2103 center_pane.setLayout(new BorderLayout(5,5));
2104 center_pane.add(labels_pane, BorderLayout.WEST);
2105 center_pane.add(values_pane, BorderLayout.CENTER);
2106
2107 button_pane.setLayout(new GridLayout(1,2,0,5));
2108 button_pane.add(ok_button);
2109 button_pane.add(cancel_button);
2110
2111 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
2112 content_pane.setLayout(new BorderLayout());
2113 content_pane.add(center_pane, BorderLayout.CENTER);
2114 content_pane.add(button_pane, BorderLayout.SOUTH);
2115
2116 setLocation((config.screen_size.width - ADD_ELEMENT_SIZE.width) / 2, (config.screen_size.height - ADD_ELEMENT_SIZE.height) / 2);
2117 }
2118
2119
2120 /**
2121 Any implementation of ActionListener must include this method so that we can be informed when an action has occured.
2122 @param event An <string>ActionEvent</strong> containing information about the event.
2123 */
2124 public void actionPerformed(ActionEvent event)
2125 {
2126 Object source = event.getSource();
2127
2128 if(source == ok_button)
2129 {
2130 TreeNode selPath = current_node.getParent();
2131 GEMSNode parent = (GEMSNode)selPath;
2132 MetadataSet currentSet = msm.getSet(current_element.getNamespace());
2133 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
2134 GEMSNode new_node = null;
2135
2136 // If this element doesn't already exist.
2137 if(!currentSet.containsElement(name_str)) //Do the renaming!
2138 {
2139 model.remove(current_node); //Hide the element that are about to rename
2140 msm.renameElement(current_element, name_str); //rename the element
2141 //Add the new element
2142 new_node = model.add(parent, current_element, GEMSNode.ELEMENT);
2143
2144 //mds_tree.setSelectionPath(new_node_path); //would like to do this but doesn't hilight tree :-(
2145 card_layout.show(details_pane, BLANK); // Show a blank panel.
2146
2147 //finish up
2148 currentSet.setSetChanged(true);
2149 atLeastOneSetChanged = true;
2150 setVisible(false);
2151 }
2152
2153 // Otherwise show an error message and do not proceed.
2154 else
2155 {
2156 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Element_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
2157 }
2158 name_str = null;
2159
2160 }
2161
2162 else if(source == cancel_button)
2163 {
2164 setVisible(false); //hide dialog
2165 }
2166 else
2167 {
2168 name_field.setText(current_element.getNameOnly()); //show old name (without namespace)
2169 setVisible(true); //Show the dialog
2170 }
2171
2172 source = null;
2173 }
2174
2175 public void dispose() {
2176 cancel_button = null;
2177 ok_button = null;
2178 name_field = null;
2179 super.dispose();
2180 }
2181 }
2182
2183
2184 /**
2185 Class to handle DELETE key presses on the tree.
2186 The class then fires the appropriate event to remove that element/set.
2187 Attributes in the table are handled directly by the RemoveAttributeActionListener
2188
2189 Author: Matthew Whyte
2190 Date last modified: 25/01/05
2191 */
2192 private class KeyPressedHandler implements KeyListener, ActionListener {
2193
2194 // All implementations of KeyListener requires these methods
2195 public void keyTyped(KeyEvent e){
2196 //Do nothing
2197 }
2198 public void keyPressed(KeyEvent e)
2199 {
2200
2201 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_DELETE) //DELETE key pressed
2202 {
2203 this.removeItem();
2204 }
2205 }
2206 public void keyReleased(KeyEvent e)
2207 {
2208 //Do nothing
2209 }
2210
2211 public void actionPerformed(ActionEvent event)
2212 {
2213 this.removeItem();
2214 }
2215
2216 public void removeItem()
2217 {
2218 boolean cont = true;
2219
2220 /**
2221 Check to see if more than one tree node/leaf is selected. If so don't continue.
2222
2223 This could be updated to delete multiple nodes/leaves in the futere.
2224 But not me and not today!
2225 */
2226 TreePath[] multiSelectionCheck = mds_tree.getSelectionPaths();
2227 if(multiSelectionCheck.length > 1)
2228 {
2229 cont = false;
2230 Toolkit.getDefaultToolkit().beep();
2231 }
2232
2233 if(cont)
2234 {
2235 //Check to see if pressed on Set or Element.
2236 TreePath selPath = mds_tree.getSelectionPath();
2237 GEMSNode t = (GEMSNode)selPath.getLastPathComponent();
2238
2239 if(t.type == T_ELEMENT) //Remove the element
2240 {
2241 RemoveElementActionListener removeElement = new RemoveElementActionListener();
2242 removeElement.actionPerformed((ActionEvent)null);
2243 }
2244 else if(t.type == T_SET) //Remove the whole set
2245 {
2246 RemoveSetActionListener removeSet = new RemoveSetActionListener();
2247 removeSet.actionPerformed((ActionEvent)null);
2248 }
2249 }
2250 }
2251 }
2252
2253
2254 private class RemoveSetActionListener
2255 implements ActionListener {
2256
2257 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
2258 * @param event An <strong>ActionEvent</strong> containing information about the event.
2259 */
2260 public void actionPerformed(ActionEvent event) {
2261 if(current_set != null) {
2262
2263 //If the current_set_filename is dls or dublin or ex and in the GLI metadata directory, then do
2264 //not let anyone remove them --Attila
2265 File current_set_filename = current_set.getFile();
2266 if(current_set_filename.toString().compareTo(new String(getGLIMetadataDirectoryPath() + "dls.mds")) == 0 ||
2267 current_set_filename.toString().compareTo(new String(getGLIMetadataDirectoryPath() + "dublin.mds")) == 0 ||
2268 current_set_filename.toString().compareTo(new String(getGLIMetadataDirectoryPath() + "ex.mds")) == 0){
2269
2270 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Cannot_Delete_Core_Sets_Error"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
2271 return;
2272 }
2273
2274
2275 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Removal", Dictionary.get("GEMS.Set") + " " + Dictionary.get("GEMS.Cannot_Undo")), Dictionary.get("GEMS.Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
2276 // Remove the currently selected set
2277 if(result == 0) {
2278
2279 ignore = true;
2280 msm.removeSet(current_set);
2281 // Clear selection
2282 mds_tree.clearSelection();
2283 model.remove(current_node);
2284 card_layout.show(details_pane, BLANK); //Show a blank panel.
2285 ignore = false;
2286
2287 }
2288 }
2289 }
2290 }
2291
2292 /** Used to enable a certain target component if and only if all the registered text fields contain non-zero length strings. */
2293 private class TextFieldEnabler
2294 implements DocumentListener {
2295 private boolean ignore = false;
2296 private Component target = null;
2297 private JTextComponent[] fields = null;
2298 public TextFieldEnabler(Component target) {
2299 super();
2300 this.target = target;
2301 }
2302 public void add(JTextComponent field) {
2303 // Record this field as being one we depend upon
2304 if(fields == null) {
2305 fields = new JTextComponent[1];
2306 fields[0] = field;
2307 }
2308 else {
2309 JTextComponent[] temp = new JTextComponent[fields.length + 1];
2310 System.arraycopy(fields, 0, temp, 0, fields.length);
2311 temp[fields.length] = field;
2312 fields = temp;
2313 temp = null;
2314 }
2315 // Add the appropriate listener
2316 field.getDocument().addDocumentListener(this);
2317 }
2318 /** Gives notification that an attribute or set of attributes changed. */
2319 public void changedUpdate(DocumentEvent e) {
2320 canEnable();
2321 }
2322 /** Gives notification that there was an insert into the document. */
2323 public void insertUpdate(DocumentEvent e) {
2324 canEnable();
2325 }
2326 /** Gives notification that a portion of the document has been removed. */
2327 public void removeUpdate(DocumentEvent e) {
2328 canEnable();
2329 }
2330 private void canEnable() {
2331 if(!ignore) {
2332 ignore = true;
2333 boolean can_enable = true;
2334 for(int i = 0; can_enable && i < fields.length; i++) {
2335 can_enable = can_enable && (fields[i].getText().length() > 0);
2336 }
2337 target.setEnabled(can_enable);
2338 ignore = false;
2339 }
2340 }
2341 }
2342
2343 private class AttributesListSelectionListener
2344 implements ListSelectionListener
2345 {
2346 private JTable table = null;
2347 public AttributesListSelectionListener(JTable table)
2348 {
2349 this.table = table;
2350 }
2351
2352 public void valueChanged(ListSelectionEvent event)
2353 {
2354 if(!event.getValueIsAdjusting())
2355 {
2356 current_attribute = table.getSelectedRow();
2357 }
2358 }
2359 }
2360
2361 private class MDSTreeSelectionListener
2362 implements TreeSelectionListener {
2363 public void valueChanged(TreeSelectionEvent event) {
2364 if(!ignore) {
2365 // Clear all variables based on previous tree selection
2366 current_element = null;
2367 current_set = null;
2368 // Now process the node selected
2369 TreePath path = event.getPath();
2370 current_node = (GEMSNode)path.getLastPathComponent();
2371 // What we show depends on the node type...
2372 AttributeTableModel atm = null;
2373 TreeSet attributes = null;
2374 current_attribute_type = current_node.getType();
2375 switch(current_attribute_type) {
2376
2377 case GEMSNode.ELEMENT:
2378 current_element = current_node.getElement();
2379 atm = current_node.getModel();
2380 if(atm == null) {
2381 atm = new AttributeTableModel(current_element.getAttributes(), Dictionary.get("GEMS.Name"), Dictionary.get("GEMS.Language_Code"), Dictionary.get("GEMS.Value"), "");
2382 //current_node.setModel(atm);
2383 }
2384 element_attributes.setModel(atm);
2385 atm.setScrollPane(element_attributes_scroll);
2386 atm.setTable(element_attributes);
2387
2388 card_layout.show(details_pane, ELEMENT);
2389 break;
2390 case GEMSNode.SET:
2391 current_set = current_node.getSet();
2392 atm = current_node.getModel();
2393 if(atm == null) {
2394 NamedNodeMap temp = current_set.getAttributes();
2395 attributes = new TreeSet();
2396 for(int i = 0; i < temp.getLength(); i++) {
2397 Attr attribute = (Attr) temp.item(i);
2398 // We don't show the namespace attribute, as it is used as a unique primary key and should never be changed or removed in itself.
2399 if(!attribute.getName().equals("namespace")) {
2400 attributes.add(new Attribute(attribute.getName(), attribute.getValue()));
2401 }
2402 attribute = null;
2403 }
2404 atm = new AttributeTableModel(attributes, Dictionary.get("GEMS.Name"), Dictionary.get("GEMS.Value"), "");
2405 temp = null;
2406 }
2407 set_attributes.setModel(atm);
2408 atm.setScrollPane(set_attributes_scroll);
2409 atm.setTable(set_attributes);
2410
2411 card_layout.show(details_pane, SET);
2412 attributes = null;
2413 break;
2414
2415 default:
2416 // Show a blank panel.
2417 card_layout.show(details_pane, BLANK);
2418 }
2419 attributes = null;
2420 path = null;
2421 atm = null;
2422 }
2423 }
2424 }
2425
2426 private class GEMSTreeCellRenderer
2427 extends DefaultTreeCellRenderer {
2428 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
2429 super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
2430 setToolTipText(value.toString());
2431 return this;
2432 }
2433 }
2434
2435
2436 //PopupListener is our main manager for all right-click popups
2437 class PopupListener extends MouseAdapter implements ActionListener{
2438 JPopupMenu setPopup;
2439 JPopupMenu elementPopup;
2440 JPopupMenu attributePopup;
2441
2442 //all of our popup menu items EVER!
2443 JMenuItem menuAddAttributeSet;
2444 JMenuItem menuAddElement;
2445 JMenuItem menuRenameSet;
2446 JMenuItem menuRemoveSet;
2447
2448 JMenuItem menuAddAttributeElement;
2449 JMenuItem menuAddSubelement;
2450 JMenuItem menuRenameElement;
2451 JMenuItem menuDeleteElement;
2452
2453 JMenuItem menuAddAttributeAttribute;
2454 JMenuItem menuEditValue;
2455 JMenuItem menuDeleteAttribute;
2456
2457 GEMS GEMSRef = null;
2458 PopupListener(GEMS g) {
2459 setPopup = new JPopupMenu();
2460 elementPopup = new JPopupMenu();
2461 attributePopup = new JPopupMenu();
2462
2463 //reference to our parent(GEMS), because some of the actionlisteners would not
2464 //work unless they were declared in GEMS, and I need a way to reference GEMS
2465 GEMSRef = g;
2466
2467 //Create the menu items
2468 menuAddAttributeSet = new JMenuItem();
2469 Dictionary.setBoth(menuAddAttributeSet, "GEMS.Add_Attribute", "GEMS.Add_Attribute_Tooltip");
2470 menuAddElement =new JMenuItem();
2471 Dictionary.setBoth(menuAddElement,"GEMS.Add_Element","GEMS.Add_Element_Tooltip");
2472 menuRenameSet = new JMenuItem();
2473 Dictionary.setBoth(menuRenameSet,"GEMS.Rename_Set", "GEMS.Rename_Set_Tooltip");
2474 menuRemoveSet = new JMenuItem();
2475 Dictionary.setBoth(menuRemoveSet, "GEMS.Remove_Set","GEMS.Remove_Set_Tooltip");
2476
2477 menuAddAttributeElement=new JMenuItem();
2478 Dictionary.setBoth(menuAddAttributeElement,"GEMS.Add_Attribute", "GEMS.Add_Attribute_Tooltip");
2479 menuAddSubelement=new JMenuItem();
2480 Dictionary.setBoth(menuAddSubelement,"GEMS.Add_Subelement", "GEMS.Add_Subelement_Tooltip");
2481 menuRenameElement=new JMenuItem();
2482 Dictionary.setBoth(menuRenameElement,"GEMS.Rename_Element", "GEMS.Rename_Element_Tooltip");
2483 menuDeleteElement=new JMenuItem();
2484 Dictionary.setBoth(menuDeleteElement,"GEMS.Remove_Element", "GEMS.Remove_Element_Tooltip" );
2485
2486 menuAddAttributeAttribute=new JMenuItem();
2487 Dictionary.setBoth(menuAddAttributeAttribute,"GEMS.Add_Attribute", "GEMS.Add_Attribute_Tooltip");
2488 menuEditValue=new JMenuItem();
2489 Dictionary.setBoth(menuEditValue,"GEMS.Edit_Value", "GEMS.Edit_Value_Tooltip");
2490 menuDeleteAttribute=new JMenuItem();
2491 Dictionary.setBoth(menuDeleteAttribute,"GEMS.Remove_Attribute", "GEMS.Remove_Attribute_Tooltip");
2492
2493 //Associate the menu items with the appropriate popups:
2494 setPopup.add(menuAddAttributeSet);
2495 setPopup.add(menuAddElement);
2496 setPopup.add(menuRenameSet);
2497 setPopup.add(menuRemoveSet);
2498
2499 elementPopup.add(menuAddAttributeElement);
2500 elementPopup.add(menuAddSubelement);
2501 elementPopup.add(menuRenameElement);
2502 elementPopup.add(menuDeleteElement);
2503
2504 attributePopup.add(menuAddAttributeAttribute);
2505 attributePopup.add(menuEditValue);
2506 attributePopup.add(menuDeleteAttribute);
2507
2508 //Add appropriate action listeners to the menu items.
2509 menuAddAttributeSet.addActionListener(new AddOrEditAttributeActionListener());
2510 menuAddElement.addActionListener(new AddElementActionListener());
2511 menuRenameSet.addActionListener(new RenameSetActionListener());
2512 menuRemoveSet.addActionListener(new RemoveSetActionListener());
2513
2514 menuAddAttributeElement.addActionListener(new AddOrEditAttributeActionListener());
2515 menuAddSubelement.addActionListener(new AddSubelementActionListener());
2516 menuRenameElement.addActionListener(new RenameElementActionListener());
2517 menuDeleteElement.addActionListener(new RemoveElementActionListener());
2518
2519 menuEditValue.addActionListener(new AddOrEditAttributeActionListener());
2520 menuDeleteAttribute.addActionListener(new RemoveAttributeActionListener());
2521 menuAddAttributeAttribute.addActionListener(new AddOrEditAttributeActionListener());
2522 }
2523
2524 public void mouseClicked(MouseEvent e) {
2525 maybeShowPopup(e);
2526 }
2527 public void mousePressed(MouseEvent e){
2528 maybeShowPopup(e);
2529 }
2530 public void mouseReleased(MouseEvent e) {
2531 maybeShowPopup(e);
2532 }
2533
2534 private void maybeShowPopup(MouseEvent e) {
2535 TreePath selPath = mds_tree.getPathForLocation(e.getX(), e.getY());
2536 Point p = null;
2537 if (e.isPopupTrigger()) {
2538
2539 if(e.getSource() == mds_tree) {
2540 try {
2541 GEMSNode t = (GEMSNode)selPath.getLastPathComponent();
2542
2543 mds_tree.setSelectionPath(selPath); //Select node right-clicked on
2544
2545 if(t.type == T_ELEMENT){
2546 elementPopup.show(e.getComponent(), e.getX(), e.getY());
2547 }
2548 else if(t.type == T_SET){
2549 setPopup.show(e.getComponent(), e.getX(), e.getY());
2550 }
2551 }
2552 catch(Exception NullPointerException) {
2553 //Right-clicked in tree area, but no item to select. Do nothing.
2554 }
2555 }
2556 else if(e.getSource() == set_attributes){ //When right-click on table of set attributes
2557 //Select the table row that was right-clicked on.
2558 p = e.getPoint();
2559 set_attributes.changeSelection(set_attributes.rowAtPoint(p), set_attributes.columnAtPoint(p), false, false);
2560 attributePopup.show(e.getComponent(), e.getX(), e.getY());
2561 }
2562 else if(e.getSource() == element_attributes) { //When right-click on table of element attributes
2563 //Select the table row that was right-clicked on.
2564 p = e.getPoint();
2565 element_attributes.changeSelection(element_attributes.rowAtPoint(p), element_attributes.columnAtPoint(p), false, false);
2566 attributePopup.show(e.getComponent(), e.getX(), e.getY());
2567 }
2568 }
2569 }
2570
2571 public void actionPerformed(ActionEvent e) {
2572 //This should never happen!
2573 System.err.println("Error: actionPerformed was called in class PopupListener. This should never happen!");
2574 }
2575 }
2576
2577 /** Wrap a ElementWrapper so we get its name when we ask for toString(), not its identifier. */
2578 private class NameElementWrapperEntry
2579 implements Comparable {
2580 private ElementWrapper element_wrapper = null;
2581 public NameElementWrapperEntry(Object object) {
2582 this.element_wrapper = (ElementWrapper) object;
2583 }
2584 public int compareTo(Object object) {
2585 return element_wrapper.compareTo(object);
2586 }
2587 public boolean equals(Object object) {
2588 return element_wrapper.equals(object);
2589 }
2590 public String toString() {
2591 return element_wrapper.getName();
2592 }
2593 }
2594}
Note: See TracBrowser for help on using the repository browser.